• Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
594
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
46
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Software Testing- Test Driven Development (TDD) with JUnit -Fernando Brito e AbreuDCTI / ISCTE-IULQUASAR Research Group
  • 2. SWEBOK: the 10 Knowledge Areas Software Requirements Software Design Software Construction Software Testing Software Maintenance Software Configuration Management Software Engineering Management Software Engineering Process Software Engineering Tools and Methods Software Quality27-Sep-11 Software Engineering / Fernando Brito e Abreu 2
  • 3. Working test first / TDD  Traditionally, code has been written using a test-last philosophy, i.e. design, code, then test  Testing after the fact is often boring  Write code “test first” instead:  Write a simple test (one assertion)  Write enough code to make the test pass  Repeat the process, ‘filling’ out the code27-Sep-11 Software Engineering / Fernando Brito e Abreu 3
  • 4. Unit testing, extreme style Tests should be an integral part of the coding process Whenever you implement a class, also make a companion test class Tests are executable documentation  Testsallow other programmers see how to use code  Therefore they are part of the specification27-Sep-11 Software Engineering / Fernando Brito e Abreu 4
  • 5. Best practices Test everything that could possibly break  This is an XP maxim and it holds A well-written test is hard to pass  If all your tests pass the first time, you are probably not testing vigorously enough All tests should pass before any update is made to a collective code base27-Sep-11 Software Engineering / Fernando Brito e Abreu 5
  • 6. Best practices When a test case fails, track down the problem by writing more tests, before going to the debugger  The more tests you have, the better Test invalid parameters to every method, rather than just valid data  Robust software needs to recognize and handle invalid data, and the tests that pass using incorrect data are often the most informative27-Sep-11 Software Engineering / Fernando Brito e Abreu 6
  • 7. The xUnit testing frameworks story Kent Beck published a unit test framework for the Smalltalk language in 1999 named SmalltalkUnit (aka SUnit) Later, Erich Gamma ported SUnit to Java, creating JUnit Many more xUnit implementations adapted to various languages and platforms were made since  CppUnit (C++), NUnit (.Net), Dunit (Delphi), VBUnit (Visual Basic), RUnit (R), PyUnit (Pyton), HtmlUnit, XMLUnit, …27-Sep-11 Software Engineering / Fernando Brito e Abreu 7
  • 8. JUnit for Eclipse Test class This bar is only green when all tests pass!Test error messages andtracing info appear here27-Sep-11 selected test casefor the Software Engineering / Fernando Brito e Abreu 8
  • 9. Building a test suite A test suite is the union of the test cases for all classes in the system A test suite should have:  One test class for each class in the system Each test class should have at least one test method (aka test case) for each method in the class under test  To be more precise, we should have a number of test cases given by the McCabe complexity metric of the target method27-Sep-11 Software Engineering / Fernando Brito e Abreu 9
  • 10. Test case stubs JUnit test case stubs can be generated with Eclipse  Since only one test case stub is generated per method, you should cut and paste those stubs if McCabe complexity metric is greater than one Method stubs look like this: @Test public final void testSomeMethod() { fail("Not yet implemented"); // TODO }27-Sep-11 Software Engineering / Fernando Brito e Abreu 10
  • 11. Test case stubs Here we choose which stubs we want to create27-Sep-11 Software Engineering / Fernando Brito e Abreu 11
  • 12. Test suite organization Test code must be separated from application  Give them each their own unique directory tree with the same package naming structure  One tree using “src” as root  Another tree using “tests” as root  This lets tests live in the same package as the objects they test, while still keeping them separate during a build27-Sep-11 Software Engineering / Fernando Brito e Abreu 12
  • 13. Test suite organization If you select a directory and do “Run As / Junit Test” all test classes contained in it (recursively) are executed. If you select a file and do “Run As / Junit Test” only the test cases in it are executed.27-Sep-11 Software Engineering / Fernando Brito e Abreu 13
  • 14. This convention is just anNaming convention example. The important thing is using a consistent convention to facilitate maintainability. Test classes  <test class name> ::= <class name>Test  e.g. ClientAccountTest, CurrencyTest, … Test cases  <test case name> ::= test[<n>]<method name>.java  The <n> counter can be discarded when we have a single test (McCabe complexity = 1)  e.g. client.testgetName(), myAccount.test1deposit(), myAccount.test2deposit(), …27-Sep-11 Software Engineering / Fernando Brito e Abreu 14
  • 15. JUnit mechanisms Annotations  The mechanism by which JUnit determines organizes and activates your test cases Assertions  The mechanism by which JUnit determines the success or failure of a test  An assert is a comparison between an expected value and an actual value27-Sep-11 Software Engineering / Fernando Brito e Abreu 15
  • 16. Annotations @BeforeClass @AfterClass @Before @After @Test @Ignore @Timeout27-Sep-11 Software Engineering / Fernando Brito e Abreu 16
  • 17. @BeforeClass This annotation allows setting up methods that will run before the full test suite contained in the class This can be used to perform time intensive activities  Example: connect to a database There is no restriction on the names of the methods, but you should use semantically meaningful identifiers @BeforeClass public void runBeforeFullSuite() { // run once before all test cases }27-Sep-11 Software Engineering / Fernando Brito e Abreu 17
  • 18. @AfterClass This annotation allows setting up methods that will run after all tests contained in the class have finished This can be used to perform clean-up activities  Example: disconnect from a database @AfterClass public void runAfterFullSuite() { // run for one time after all test cases }27-Sep-11 Software Engineering / Fernando Brito e Abreu 18
  • 19. @Before This annotation allows setting up all test cases, since the corresponding method will run before each test case A @Before method can prepare the test environment  e.g. read input data, initialize the class @Before public void runBeforeEveryTest() { simpleMath = new SimpleMath(); }27-Sep-11 Software Engineering / Fernando Brito e Abreu 19
  • 20. @After This annotation allows tearing down test methods since it will run after every test case @After public void runAfterEveryTest() { simpleMath = null; }27-Sep-11 Software Engineering / Fernando Brito e Abreu 20
  • 21. @Test Mark your test cases with @Test annotations You don’t need to prefix your test cases with “test”, although this is a good naming convention @Test public void testAddition() { assertEquals(12, simpleMath.add(7, 5)); } @Test public void testSubtraction() { assertEquals(9, simpleMath.subtract(12, 3)); }27-Sep-11 Software Engineering / Fernando Brito e Abreu 21
  • 22. @Test Another example: @Test public void listEquality() { List<Integer> expected = new ArrayList<Integer>(); expected.add(5); List<Integer> actual = new ArrayList<Integer>(); actual.add(5); assertEquals(expected, actual); }27-Sep-11 Software Engineering / Fernando Brito e Abreu 22
  • 23. @Test(timeout = <delay>) Define a timeout period in milliseconds with “timeout” parameter The test fails when the timeout period exceeds @Test(timeout = 1000) public void infinity() { while (true) ; }27-Sep-11 Software Engineering / Fernando Brito e Abreu 23
  • 24. @Test(expected = <exception>.class) Tests succeeds if the method throws the exception Notice that the fail command is not executed because the exception is raised and caught by JUnit, that sees any further.27-Sep-11 Software Engineering / Fernando Brito e Abreu 24
  • 25. @Ignore Use this annotation for test cases you want to ignore  You can add a string parameter that defines the reason of ignorance This may be useful if the underlying code has been changed and the test has not yet been adapted @Ignore("Not Ready to Run") @Test public void multiplication() { assertEquals(15, simpleMath.multiply(3, 5)); }27-Sep-11 Software Engineering / Fernando Brito e Abreu 25
  • 26. Assertions assertEquals assertEquals for arrays assertNull / assertNotNull assertSame / assertNotSame assertTrue / assertFalse fail27-Sep-11 Software Engineering / Fernando Brito e Abreu 26
  • 27. assertEquals  This assertion states that:  expected.equals(actual) returns true, or  both objects are null  A message is printed if supplied, when a test fails  The equality test for a double or a float should specify a maximum tolerance range (the delta), to cope with floating point errors  There are overloaded versions of this method for all Java’s primitive types assertEquals(Object expected, Object actual) assertEquals(String message, Object expected, Object actual) assertEquals(Object expected, Object actual, delta) assertEquals(String message, Engineering /expected, eObject actual, delta)27-Sep-11 Software Object Fernando Brito Abreu 27
  • 28. assertEquals for arrays  Two arrays are equal if they have the same length and each element is equal to the corresponding element in the other array; otherwise, they’re not.public static void assertEquals(Object[] expected, Object[] actual);public static void assertEquals(String message, Object[] expected, Object[]actual);27-Sep-11 Software Engineering / Fernando Brito e Abreu 28
  • 29. assertNull / assertNotNull  This asserts that an object reference equals null, printing a message otherwise (if supplied) assertNull(Object object), assertNull(String message, Object object)  This asserts that an object reference is not null, printing a message otherwise (if supplied) assertNotNull(Object object), assertNotNull(String message, Object)27-Sep-11 Software Engineering / Fernando Brito e Abreu 29
  • 30. assertSame / assertNotSame  Asserts that the two objects are the same, printing a message otherwise (if supplied)  Thisis a stricter condition than simple equality, as it compares the object identities using expected == actual assertSame(Object expected, Object actual) assertSame(String message, Object expected, Object actual)  Asserts that the two objects are not the same, printing a message otherwise (if supplied) assertNotSame(Object expected, Object actual) assertNotSame(String message, Object expected, Object actual)27-Sep-11 Software Engineering / Fernando Brito e Abreu 30
  • 31. assertTrue / assertFalse  Asserts that the condition is true, printing a message otherwise (if supplied) assertTrue(boolean condition) assertTrue(String message, boolean condition)  Asserts that the condition is false, printing a message otherwise (if supplied) assertFalse(boolean condition) assertFalse(String message, boolean condition)27-Sep-11 Software Engineering / Fernando Brito e Abreu 31
  • 32. fail This forces a failure. This is useful to close off paths through the code that should not be reached fail() fail(String message)27-Sep-11 Software Engineering / Fernando Brito e Abreu 32
  • 33. More Reading http://www.junit.org/index.htm http://open.ncsu.edu/se/tutorials/junit/ http://www.cs.umanitoba.ca/~eclipse/10-JUnit.pdf http://supportweb.cs.bham.ac.uk/documentation/tutorial s/docsystem/build/tutorials/junit/junit.pdf http://junit.sourceforge.net/javadoc/junit/framework/27-Sep-11 Software Engineering / Fernando Brito e Abreu 33