In a recent entry, Martin Fowler explains the reason behind JUnit reinstantiating your JUnit class before invoking each test method. He concludes by showing the following example:
[TestFixture] public class ServerTester { private IList list = new ArrayList(); [Test] public void first() { list.Add(1); Assert.AreEqual(1, list.Count); } [Test] public void second() { Assert.AreEqual(0, list.Count); } }and pointing out that this example passes with JUnit but fails with NUnit and TestNG.
Here is why.
Remove mentally the annotations from the code above ([TestFixture], [Test]) and read the code just like if it were standard Java/C# code. And now, predict its output, knowing that first() is invoked first and then second().
It seems pretty obvious this code will fail in Java and in C#.
So why should your test framework behave differently?
By the way, here is the correct way to write this test with TestNG:
@Test public class ServerTester { private IList list = null; @Configuration(beforeTestMethod = true) public void init() { list = new ArrayList(); } public void first() { list.Add(1); Assert.AreEqual(1, list.Count); } public void second() { Assert.AreEqual(0, list.Count); } }Quick explanation:
- The @Test annotation at the class level indicates that all the public methods in this class are test methods, so there is no need to add individual annotations @Test on each method.
- The @Configuration annotation indicates that the method init() should be invoked every time before a test method is invoked.
How would you feel if Java invoked your constructor every time before invoking your methods?