1 / 20

JUnit intro

JUnit intro. Kalvis Apsitis. What are “Programmer Tests”?. Programmer Testing is the testing performed by a developer with the goal of verifying the correct functioning of his/her own code

neith
Download Presentation

JUnit intro

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. JUnit intro Kalvis Apsitis

  2. What are “Programmer Tests”? • Programmer Testing is the testing performed by a developer with the goal of verifying the correct functioning of his/her own code • Programmer Tests are automated unit tests that exercise program units such as classes and methods , not the complete features or requirements supported by the software as a whole • Important distinction: if it’s not automated, it’s not really programmer testing – that’s exploratory testing.

  3. Safety Net • Having a good test coverage with an automated unit test harness… • prevents a system from becoming legacy(*), and • enables effective refactoring, because it also prevents regression • Metaphor: Mold • Michael Feathers defines “legacy code” as code without tests

  4. Michael Feathers (2004) • I don't care how good you think your design is. If I can't walk in and write a test for an arbitrary method of yours in five minutes its not as good as you think it is, and whether you know it or not, you're paying a price for it: • You think your design is good? Pick a class, any class, and try to instantiate it in a test harness. • Can you make this class work outside the application? • Can you get it to the point where you can tinker with it, in real time, build it alone in less than a second, and add tests to find out what it really does in certain situations.

  5. Available tools for Java • JUnit (www.junit.org) • The de facto Java unit testing framework • Extremely simple, suitable for unit/component testing • Plenty of extensions for J2EE, for example • TestNG (testng.org) • Very close to JUnit but not quite • Can configure test groups/suites in a more flexible way (it is usable for some integration testing)

  6. JUnit Concepts • Test suite: Executable row of several Test cases • Test case: Java class containing test methods • Test fixture: the initial state of a Test Case, consisting of the member variables initialized through a method annotated with @Before. E.g. @Before public void setUp() { … } • Test method: a no-argument method of a TestCase class annotated with @Test (represents a single logical test) For example: @Test public void someMethod() { … } ============ Only things to do in “@Test testA(){...}” methods is business logic + assertions. Test fixture contains everything else needed to run the tests (it is initialized in "@Before setUp(){...}").

  7. TestCase lifecycle @Before public void setUp() {...} gets called once before each test method is executed @After public void tearDown() {...} gets called once after each test method has been executed – regardless of whether the test passed or failed (or threw some other exception). • Each test method gets called exactly once in some order (test methods should be isolated, so the order does not matter). • The same instance of a TestCase may or may not be used for executing the tests – don’t depend on the constructor, use setUp() for setup!

  8. Suite Example import org.junit.*; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses(value = {TestCase1.class, TestCase2.class}) public class SomeSuite { // any code; // may contain TestCase1, TestCase2 // as inner classes, if their fixtures have much // in common }

  9. Simple Annotations in a TestCase import org.junit.*; public class TestCase1 { @Before protected void setUp() {super.setUp();} @After protected void tearDown() {super.tearDown();} @Test public void methodOne() { ... } @Test(expected = RuntimeException.class) public void testSomeException() { ... } @Ignore(value = "Test method not ready") @Test public void ignoredTestCase() { ... } }

  10. Simple TestCase (3) import org.junit.*; public class TestCalculator { private Calculator calculator; protected void setUp() { super.setUp(); calculator = new Calculator(); } @Test public void addingPositiveIntegers() { int expected = 5; int actual = calculator.add(2, 3); assertEquals("2 + 3 should be 5", expected, actual); } }

  11. Test anything that could fail import org.junit.*; public class TestCalculator { private Calculator calculator; @Before protected void setUp() { … } @After protected void tearDown() { … } @Test public void addingPositiveIntegers() { … } @Test public void addingNegativeIntegers() { … } @Test public void addingZeroes() { … } @Test public void addingPositiveToNegative() { … } } How many method calls are executed?

  12. Test Granularity • Each unit test should check one specific piece of functionality. Do not combine multiple, unrelated tests into a single testXXX( ) method. • If the first assertEquals( ) in some method fails, the remainder is not executed. You won't know if the other (unrelated) asserts are functional. • One method may contain several asserts, if they are related, i.e. if the failure of one assert would cause failures in other asserts anyway.

  13. Exercise 1:Write a TestCase • Task: Write a JUnit TestCase for the Template class, place it under sem02-demo/src/main/java/exercise1/TemplateTest.java • There’s a bug in Template class. Try to find it!

  14. Simple TestSuite import org.junit.*; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses(value = {CalculatorIntegerTest.class, CalculatorFloatingPointTest.class, CalculatorLogarithmsTest.class }) public class CalculatorTestSuite { // Can leave empty }

  15. Exercise 2:Write a TestSuite • Task: • Write a JUnit TestSuite exercise2.AllTests that collects all the TestCase classes from sem02_demo/src/test/java/exercise2.

  16. What if I need to do something expensive in setUp()? • If you need to perform some kind of one-time setup before running the test methods of a TestCase (and can’t/won’t replace the expensive stuff with a mock implementation), use @BeforeClass annotation: public class Example { @BeforeClass public static void onlyOnce() { } @Before public void beforeEachTest() {} @Test public void one() { ... } @Test public void two() { ... } }

  17. Example of @BeforeClass public class InterestCalculatorTestWithTestSetup { private static double interestRate, loanAmount; private static int loanDuration; public static Test suite() { TestSuite suite = new TestSuite(InterestCalculatorTestWithTestSetup.class); TestSetup wrapper = new TestSetup(suite) { public void setUp() throws IOException { ResourceBundle bundle = ResourceBundler.getBundle( InterestCalculatorTestWithTestSetup.class.getName()); inrerestRate = Double.parseDouble(bundle.getString(“interest.rate”)); loanAmount = Double.parseDouble(bundle.getString(“loan.amount”)); loanDuration = Interest.parseInt(bundle.getString(“loan.duration”)); } }; return wrapper; } public void testInterestCalculation() { … } }

  18. Assertions • We already saw one assertion in action, the assertEquals() method • There are a bunch others – take a look at the Javadocs for org.junit.Assert • The most often used assertions –assertEquals(), assertNull(), assertSame(), assertTrue() and their opposites – are enough for most situations and the rest you can easily write on your own. • Assert.fail() is used, if control should not reach that line in the test - this makes the test method to fail.

  19. Testing Expected Exceptions @Test public void method1() { try { Template t = new Template( "My ${f\\oo template" ); fail("Should NOT allow unterminated variables in " + t); } catch (IllegalArgumentException expected) {} } @Test(expected=IllegalArgumentException.class) public void method2() { new Template( "This is my ${f\\oo template" ); } First approach is longer, but allows more precise control, where exactly the test method fails.

  20. What happens when an assertion fails? • The failed assertions create a org.junit.runner.notification.Failure when they fail. • JUnit tags the test as “failure” for later reference. • If a test throws any other exception (e.g. NullPointerException), JUnit again catches these but tags the test as “error” instead of “failure”.

More Related