I'm creating TestNG.xml programatically and running tests in parallel.
The issue is:
- I need to run Test2 after Test1
I tried Using 'dependsOnGroup' by assigning Test1 to a group and then asking Test2 to dependOn Test1's group.
But when I run the test suite, only Test1 will get Executed, Test2 will be skipped.
No errors reported.
#Test(groups = {"FirstTest"})
public class Test1 {
public void hello(){
syso("Test1");
}
}
#Test(groups = {"SecondTest"}, dependsOnGroups= {"FirstTest"}, alwaysRun=true)
public class Test2 {
public void hi(){
syso("Test2");
}
}
I'm using TestNG.6.9.6.jar
Adding priority would do what you need. #Test(priority=1). The lower priority would execute first.
#Test(priority=1)
public class Test1 {
public void hello(){
syso("Test1");
}
}
#Test(priority=2)
public class Test2 {
public void hi(){
syso("Test2");
}
}
It will first run Test1 and then Test2. So whichever classes you put in your test suite, it would consider the priorities of all the test functions in all it's classes.
Should do the needful for you in a lesser complicated way.
I hope it helps. :)
You can also use the dependsOnMethods() method instead of dependsOnGroup().
Related
Is there any way that I can run a class 3 times or more in Selenium. So it runs in below order:
method1
method2
method3
method1
method2
method3
method1
method2
method3
import com.test
Class A{
#Test(priority =1)
public void method1(){`System.out.print('method1');`}
#Test(priority =2)
public void method2(){`System.out.print('method2');`}
#Test(priority =3)
public void method3(){`System.out.print('method3');`}
}
As far as I know, there is no easy way in TestNG to do so. Annotation parameter invocationCount only works on method level, not on class, so annotating your class with #Test(invocationCount = 3) doesn't work.
As you're mentioning Selenium, my guess is you are trying to automate some repeated actions on a webpage. If so, then I think ideologically your best bet is to extract code from these three methods and just write another test that calls those internals, like this:
#Test(priority = 1)
public void method1() {
stuff1();
}
#Test(priority = 2)
public void method2() {
stuff2();
}
#Test(priority = 3)
public void method3() {
stuff3();
}
#Test
public void complexTest() {
for (int i = 0; i < 3; i++) {
stuff1();
stuff2();
stuff3();
}
}
private void stuff1() {
System.out.print("method1");
}
private void stuff2() {
System.out.print("method2");
}
private void stuff3() {
System.out.print("method3");
}
It's a good practice to treat each test as atomic test that can either fail or pass, and if you want to test some scenario that does particular set of actions three times, better introduce new test for this and make it clearly and explicitly "tell a story" of test.
I have two classes that each implement something differently but the tests are the same for both. Each class does some things that would affect the other class if they run in parallel, so they can't run in parallel. (that's the rationale behind the code below)
If you run the class Both, see below, in Eclipse, as a TestNG test, one would expect it to run tests test1 and test2 of class ClassAAA first and then the same test methods for ClassBBB, because ClassBBB's group annotations specify that it depends on ClassAAA's annotation.
However, what you find out is that, seemingly, TestNG has a different way of looking at it, and, "seemingly", it ignores the group order and runs the tests of the two clases in parallel.
class Both {
#Test(groups={"base"})
public static abstract class BothBase {
#Test public void test1() { System.out.println("test1"+name()); }
#Test public void test2() { System.out.println("test2"+name()); }
protected String name() {
String s = getClass().getName();
s = s.substring( 1 + s.lastIndexOf("$"));
return " - " + s;
}
}
#Test(groups={"gr1"})
public static class ClassAAA extends BothBase { }
#Test(groups={"gr2"},dependsOnGroups={"gr1"})
public static class ClassBBB extends BothBase { }
}
The output is:
test1 - ClassAAA
test1 - ClassBBB
test2 - ClassAAA
test2 - ClassBBB
One way, which i don't like, to try to "force" it to honor the desired group order, is to add a dummy test method to the leaf classes, as follows:
#Test(groups={"gr1"})
public static class ClassAAA extends BothBase {
#Test public void dummyTestMustBeInAllLeavesToEnforceGroupOrder() {
System.out.println("dummyTestMustBeInAllLeavesToEnforceGroupOrder"+name());
}
}
#Test(groups={"gr2"},dependsOnGroups={"gr1"})
public static class ClassBBB extends BothBase {
#Test public void dummyTestMustBeInAllLeavesToEnforceGroupOrder() {
System.out.println("dummyTestMustBeInAllLeavesToEnforceGroupOrder"+name());
}
}
This still doesn't completely do what one would expect. The output is:
test1 - ClassAAA
test2 - ClassAAA
test2 - ClassBBB
dummyTestMustBeInAllLeavesToEnforceGroupOrder - ClassAAA
test1 - ClassBBB
dummyTestMustBeInAllLeavesToEnforceGroupOrder - ClassBBB
This means that it started running the tests of ClassBBB before finishing the tests of ClassAAA.
I don't like the fact that i have to add a dummy/unrelated method to each, to get TestNG to understand that they cannot be run in parallel. In fact, i don't care which class runs first... And, i didn't really accomplish what i wanted because they are still running in parallel.
The stupidest way to do this, which would accomplish my goal is to move the tests from the base class to each of the leaf classes - is that how you are suppose to do these things in TestNG?
Is there another way of doing that? i'm sure someone is going to suggest priorities - but again, that does not convey the true intention - i don't have any priority - just don't want them to run in parallel. Also i don't want to write XML files...
This problem is coming due to static inner classes. Try below code you will get required output
import org.testng.annotations.Test;
#Test(groups={"base"})
public abstract class BothBase {
#Test public void test1() { System.out.println("test1"+name()); }
#Test public void test2() { System.out.println("test2"+name()); }
protected String name() {
String s = getClass().getName();
s = s.substring( 1 + s.lastIndexOf("$"));
return " - " + s;
}
}
#Test(groups={"gr1"})
class ClassAAA extends BothBase { }
#Test(groups={"gr2"},dependsOnGroups={"gr1"})
class ClassBBB extends BothBase { }
Many ways
Simplest - priority
Bit harder( groups)
Check testng manual(for ex. this http://www.mkyong.com/tutorials/testng-tutorials/).
I am running some JUnit tests programatically with JUnitCore, and I want to get some data out of the test class once it is finished (so #AfterClass). Here is a pseudocode example of the constraints I am working under:
public class A {
public static String testData;
public static void runTest() {
JUnitCore juc = new JUnitCore();
juc.run(B);
// This is where I would like to access testData for this
// particular run
}
public static void setTestData(String s) {
testData = s;
}
}
public class B {
// Some #Test methods and stuff omitted
#AfterClass
public static void done(String s) {
A.setTestData(someData);
}
}
My problem is that different threads might be calling runTest(), so testData might be wrong. How do I work around this? I'm so lost.
If you really need/want to go with this design, you can make testData a java.lang.ThreadLocal<String>. This will solve the multi-threading issue.
I was annoyed to find in the Parameterized documentation that "when running a parameterized test class, instances are created for the cross-product of the test methods and the test data elements." This means that the constructor is run once for every single test, instead of before running all of the tests. I have an expensive operation (1-5 seconds) that I put in the constructor, and now the operation is repeated way too many times, slowing the whole test suite needlessly. The operation is only needed once to set the state for all of the tests. How can I run several tests with one instance of a parameterized test?
I would move the expensive operation to a #BeforeClass method, which should execute just once for the entire parameterized test.
A silly example is shown below:
#RunWith(Parameterized.class)
public class QuickTest {
private static Object expensiveObject;
private final int value;
#BeforeClass
public static void before() {
System.out.println("Before class!");
expensiveObject = new String("Just joking!");
}
#Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { { 1 }, { 2 } });
}
public QuickTest(int value) {
this.value = value;
}
#Test
public void test() {
System.out.println(String.format("Ran test #%d.", value));
System.out.println(expensiveObject);
}
}
Will print:
Before class!
Ran test #1.
Just joking!
Ran test #2.
Just joking!
I have a method and wish to test it with different values. My question is: how can I write a JUnit test that would test the same method with different values?
You can take a look at parametrized tests like in example.
You can also use theories which is more convenient in a lot of cases.
JUnit4 supports parameterized tests for just this purpose.
See this tutorial.
I suggest you create a different unit test for each one of your (overloaded) function definitions, because arguably you are testing in fact different functions. For instance:
class MainClass {
public void method( int param) {... }
public void method( String param) { ...}
}
class MainClassTest {
#Test
public void methodIntTest() {
//call method(int)
}
#Test
public void methodStringTest() {
//call method(String)
}
}