TestNG: constant NPE on #AfterMethod - java

I have randomly failing tests no my CI server.
The problem that I'm getting NullPointerException's within tearDown() method.
The common structure which causes this behavior is simple:
#Test
class MyRandomlyFailingTest extends AbstractTestNGSpringContextTests {
#Autowired
private SomeSpringBean someSpringBean;
#BeforeMethod
public void beforeMethod() {
someSpringBean.addTestData("");
}
#AfterMethod
public void afterMethod() {
someSpringBean.removeTestData("");
}
}
So I have randomly null fields in #AfterMethod which were obviously fine when running tests. But somehow it happens that fields are null again.
#Autowired is provided by spring 3.2
So I can't find the reason why it happens. Only solution to this is to stop using #AfterMethod annotations at all

Related

DefaultRollback after running all test cases

I have an Integration test as shown below, and I want to rollback the changes to the database after going through the test cases. Now my question is is there a way to prevent default rollback from happening after each test case and have a roll back once all the test cases are done.
After surfing a bit I found that TestNG can be helpful, but I don't want to use that. Is there any other alternative?
#TransactionConfiguration(transactionManager = "myTransactionManager", defaultRollback = true)
public class TestDependencies extends testBase {
#Test
public void testSetupData() throws SQLException, Exception{
//Some initial setup code.
}
#Test
public void testFunctionality throws Exception{
//here i will further test some more functionality
}
}
If all your test cases that require rollback are in one class, the junit #afterclass annotation will run this method after all #test methods are executed.
#AfterClass
public static void Cleanup() {
txManager.rollback();
}
txManager should be wired up to your DataSourceTransactionManager bean.

How to listen to Test Suite changes in order to change some configurations

I have many Spring Test classes (defined using #RunWith(SpringJUnit4ClassRunner)) that I want to group in test suites so that I load new configurations once for every suite instead of for every test class.
Right now I have a TestExecutionListener listener to every Spring test that will reload the configurations, but I want to save that since many tests share the same configurations.
Sadly, niether Spring supports listening to JUnit TestSuites nor JUnit supports the listener concept for TestSuites.
If you wish to perform actions before/after a junit test suite, you can use #BeforeClass and #AfterClass, or even #ClassRule. You can do your setup in there for the entire suite. Using the following example:
#RunWith(Suite.class)
#SuiteClasses({ ExpectedFailureTest.class, RetryTest.class })
public class BeforeClassSuite {
#BeforeClass
public static void beforeClass() {
System.out.println("beforeClass");
}
#AfterClass
public static void afterClass() {
System.out.println("afterClass");
}
#ClassRule
public static ExternalResource resource = new ExternalResource() {
#Override
protected void before() throws Throwable {
System.out.println("before");
};
#Override
protected void after() {
System.out.println("after");
};
};
}
This produces as output:
before
beforeClass
... output from tests
afterClass
after

Accessing spring context in testng's #BeforeTest

I would like to register some web scopes to the spring context in my #BeforeTest method. But it turns out that spring context is still null at that point.
The test runs fine though, if I change into #BeforeMethod. I wonder how I can access the context in #BeforeTest, because I don't want the scope registration code to be repeated for each test methods.
Below are my code snippets.
public class MyTest extends MyBaseTest {
#Test public void someTest() { /*...*/ }
}
#ContextConfiguration(locations="/my-context.xml")
public class MyBaseTest extends AbstractTestNGSpringContextTests {
#BeforeTest public void registerWebScopes() {
ConfigurableBeanFactory factory = (ConfigurableBeanFactory)
this.applicationContext.getAutowireCapableBeanFactory();
factory.registerScope("session", new SessionScope());
factory.registerScope("request", new RequestScope());
}
/* some protected methods here */
}
Here's the error message when running the test:
FAILED CONFIGURATION: #BeforeTest registerWebScopes
java.lang.NullPointerException
at my.MyBaseTest.registerWebScopes(MyBaseTest.java:22)
Call springTestContextPrepareTestInstance() in your BeforeTest method.
TestNG runs #BeforeTest methods before #BeforeClass methods. The springTestContextPrepareTestInstance() is annotated with #BeforeClass and sets up the applicationContext. This is why the applicationContext is still null in a #BeforeTest method. #BeforeTest is for wapping a tagged group of tests. (It does not run before each #Test method, so it's a bit of a misnomer).
Instead of using #BeforeTest, you should probably use #BeforeClass (which is run once, before the first #Test in the current class). Be sure it depends on springTestContextPrepareTestInstance method, as in
#BeforeClass(dependsOnMethods = "springTestContextPrepareTestInstance")
public void registerWebScopes() {
ConfigurableBeanFactory factory = (ConfigurableBeanFactory)
this.applicationContext.getAutowireCapableBeanFactory();
factory.registerScope("session", new SessionScope());
factory.registerScope("request", new RequestScope());
}
The #BeforeMethod works, too (as you mentioned) because they run after #BeforeClass methods.

Run External Command Before JUnit Tests in Eclipse

Is it possible to run an external command before running tests in a given JUnit file? I run my tests using the Eclipse's Run command. Using JUnit 4.
Thanks.
Very vague question. Specifically, you didn't mention how you are running your JUnit tests. Also you mentioned 'file', and a file can contain several JUnit tests. Do you want to run the external command before each of those tests, or before any of them are executed?
But more on topic:
If you are using JUnit 4 or greater then you can tag a method with the #Before annotation and the method will be executed before each of your tagged #Test methods. Alternatively, tagging a static void method with #BeforeClass will cause it to be run before any of the #Test methods in the class are run.
public class MyTestClass {
#BeforeClass
public static void calledBeforeAnyTestIsRun() {
// Do something
}
#Before
public void calledBeforeEachTest() {
// Do something
}
#Test
public void testAccountCRUD() throws Exception {
}
}
If you are using a version of JUnit earlier than 4, then you can override the setUp() and setUpBeforeClass() methods as replacements for #Before and #BeforeClass.
public class MyTestClass extends TestCase {
public static void setUpBeforeClass() {
// Do something
}
public void setUp() {
// Do something
}
public void testAccountCRUD() throws Exception {
}
}
Assuming you are using JUnit 4.0, you could do the following:
#Test
public void shouldDoStuff(){
Process p = Runtime.getRuntime().exec("application agrument");
// Run the rest of the unit test...
}
If you want to run the external command for every unit test, then you should do it in the #Before setup method.

TestNg's #BeforeTest on base class only happening once per fixture

I'm trying to use #BeforeTest to get code to ... run once before every test.
This is my code:
public class TestBase {
#BeforeTest
public void before() {
System.out.println("BeforeTest");
}
}
public class TestClass extends TestBase{
#Test
public void test1(){}
#Test
public void test2(){}
}
"BeforeTest" is only printed once, not twice. What am I doing wrong?
Use #BeforeMethod, not #BeforeTest.
The meaning of #BeforeTest is explained in the documentation.
"BeforeTest" is only printed once, not twice. What am I doing wrong?
***Sorry. I haven't noticed that you is written #BeforeTest , but in your example #BeforeTest almost equals #BeforeClass , and better to use #BeforeClass , when you haven't anymore test classes.
#BeforeClass" should be declared in same class that your tests methods, not differently!
//Example
package test;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class Tests {
private String bClass;
private String bMethod1;
private String bMethod2;
#BeforeClass
public void beforeClass() {
bClass = "BeforeClass was executed once for this class";
}
#BeforeMethod
public void beforeMetodTest1() {
bMethod1 = "It's before method for test1";
}
#Test
public void test1() {
System.out.println(bClass);
System.out.println(bMethod1);
}
#BeforeMethod
public void beforeMethodTest2() {
bMethod2 = "It's before method for test2";
}
#Test
public void test2() {
System.out.println(bClass);
System.out.println(bMethod2);
}
}
#BeforeClass will executed once, before your all tests methods in this class. #BeforeMethod will executed before test method, before which it is written.
#BeforeClass may be only one in test class, in difference #BeforeMethod!(If it is some #BeforeClass, they are carried out by turns, but it not a correct composition of the test)
P.S. Sorry for my English :)
According to documentation, a method annotated with #BeforeTest is run before any #Test method belonging to the classes inside the tag is run.
From my experience:
Each #BeforeTest method is run only once
If you have several #BeforeTest methods, the order of their execution depends on the order of the class containing those #BeforeTest method.
You could test this by setting up a simple example.
If you use #beforeTest, that method will be run once in the beginning of every <test> (we specify in the test suit xml file) if that test contains that class
All the #befortests within all the classes within a <test> will be executed at the beggining of that test
Official Documentations are so unclear and mostly ambiguous. This is why many don't like to read it. Not to mention no real-life examples shown.
If you are trying to get code to run once before every test, then you are looking for #BeforeMethod, not #BeforeTest. Because each of your tests independently considered methods.
#BeforeMethod runs before each method. I see you have two methods with the names test1() and test2(). Expect BeforeMethod to run before each of them.
#BeforeTest runs only once before ALL of your tests (test-methods). In Selenium, WebDriver is called once, this is better practice for testing.
#BeforeMethod will invoke WebDriver before each test, this is not good practice, especially when you have regression tests with hundreds of them to run.
For example, if you run this code (these are separate classes, not inner to each other, only showing for demonstration purposes here):
public class TestClass extends Base {
#Test
public void test1() {
System.out.println("Running Test 1");
}
#Test
public void test2() {
System.out.println("Running Test 2");
}
}
public class Base {
#BeforeTest
public void beforeTest() {
System.out.println("Before Test");
}
#AfterTest
public void afterTest() {
System.out.println("After Test");
}
#BeforeMethod
public void beforeMethod() {
System.out.println("Before Method");
}
#AfterMethod
public void afterMethod() {
System.out.println("After Method");
}
}
And you will get this as an output:
Before Test
Before Method
Running Test 1
After Method
Before Method
Running Test 2
After Method
After Test
As you can see BeforeMethods run before each test while BeforeTest and AfterTest run only once before and after completing ALL tests.
Hope this clarified the difference for you.

Categories

Resources