I want to run selenium tests in TestNg in parallel that use the @dataprovider. Ideally tests are parallel by method (one test = one method) and not simple suite parallelism by
You don't really need to use a Factory. If I were you I would call this code within the dataprovider method:
driver = getBrowser(browser);
Then, return the driver instances as a 2nd column of args to the test method. Doing it that way allows the dataprovider to generate browser instances. To improve on that, you could instead use the builder design pattern, in the form of a DriverHelper class, that could replace the getBrowser method with a way to generate a much more specific driver configuration before passing the driver instance into the test method.
NOTE: Keep in mind that if you ever want to use Spring to load your drivers in the future, then this method won't work at all. In fact, you wont be able to use a DataProvider at all. But, if your not using Spring, then I would say this is the most elegant way of doing it.
I had the same experience about dataProvider. In my case I used dataProvider's (parallel=true) attribute though. There are two solutions to your problem.
Use dataProvider and in test class and use factory annotation for your constructor. In the factory annotation's attribute, use dataProvider="Your dataProvider's name". In the testng.xml, instead of parallel=methods, use parallel=instances.
The drawback of the above approach is that when you get the report; may be it is maven- surefire, testng Eclipse report or reportNG report, you do not see parameters passed up front. To overcome this, you can use the following approach.
Create a factory class and instantiate your test class in the factory method using a for loop. (Start for loop from 0.) In the test class define a constructor which receives a parameter from factory class. Define a dataProvider in this test class which can use the parameter (data-point) received in the constructor. Define a BeforeMethod or BeforeClass which can use that parameter or data point and Your test methods should have the "dataProvider" attribute pointing to the desired dataProvider. Again, in testng.xml use parallel="instances".
Also, use try/catch block for instantiating driver object and closing the browser. This will help you in avoiding skips due to failure of setUp of tearDown method.