testing with junit - university of...
TRANSCRIPT
Testing with JUnit
1
What are we doing here?
• Learning the mechanics of how to write tests in Java using JUnit • Without considering issues like coverage
• Using JUnit is sometimes called unit testing • Unit testing is great for testing the functionality of
classes • Unit testing is used in Test Driven Development
(TDD)
2
Origins and current status
3
Origins
• Kent Beck developed the first automated test tool for in mid-90’s • XUnit, developed for Smalltalk
• Beck and Gamma developed JUnit on a flight from Zurich to Washington DC • Martin Fowler: “Never in the field of software development was so much owed by so many to so few lines of code.”
4
4
Currently
• Junit is now the standard tool for Test-Driven Development in Java
• Junit test generators now part of many Java IDEs (Eclipse, JBuilder, Intellij)
• Language similar to JUnit have been developed for other languages (Perl, C++, Python, Visual Basic, C#, …)
5
5
A simple example
6
Stack: A poor implementation
7
7
But let’s test it anyway - detail follows
8
8
One class for the tests
• Call it SomethingTest • Something = the class you are testing
• Put the test subject in the class as an instance variable
9
9
A number of tests may appear in the class• Each called testSomething • Each prefixed with ‘@Test’ (no quotes, no ‘;’)
• This is a JUnit 4 feature, use JUnit 4
10
10
Demo
• Explore (and run) the tests
11
11
More detail
• Seems reasonable... !!!!
• But it assumes we have initialised ‘s’ , our stack implementation
12
12
Pre test-initialisation
• Use the ‘@Before’ tag for the method ‘setUp’ • setUp is then run before each test !!!!
13
13
What if we didn’t have a pre-test setup?• Eg....
14
14
What’s the problem?• JUnit’s test runner can run all the tests in our test
class, assume we run these tests in this order..
15
15
Summary: To provide test independence• We need to set up tests to run independently • ‘@Before’ tags a setup method to
run immediately before each test • Similarly ‘@After’ tags a teardown method to run
after each test runs • Do we need a teardown method for this example? !
• Default behaviour for independent tests • Tests run in a random order = good practice • You can change this, see the next slides and
the JUnit documentation16
16
Test order
• Not determined, eg Java 1.7 executes tests in a random order
• Annotate the class if you want a particular order !!!!
• Ordering • JVM, DEFAULT, NAME_ASCENDING • Nothing for ‘in-class declaration’ order
17
17
Test order example
18
18
On screen demo
• Let’s play around with the tests.... • Wow, with a test suite we can refactor our
implementation safely • I did that to provide a better stack implementation
19
19
More about assertions, good style
20
assertThat and matcher statements
• Using ‘assertThat’ improves readability • assert that x is 3 • assertThat( x, is(3) ); • assertThat(<value>, is(<expected value>)) • assertThat(<value>, <matcher statement>)
• Matcher statements • is(....), lessThan(....), sameInstance(....) • Matchers are defined in
• org.hamcrest.CoreMatchers • Only two non-deprecated matchers in
org.junit.matchers.JUnitMatchers 21
21
Old and new styles
!!!!!!!
• Note the extra (first) argument to ‘assertThat’ • do we need it?
• Demo both tests • Note different output 22
22
Some matchers
• equalTo(....) • is(....) • not(....) note not(equalTo(....)) etc • nullValue(....), notNullValue(....) • instanceOf(....) • hasItemInArray(....)
23
23
Combining matchers
• There are ways of writing assertions to perform logical operations
• Lets test that a variable ‘responseString’ contains either ‘colour’ or ‘color’assertThat( responseString, anyOf( containsString("color"), containsString("colour") ) );
!• This kind of construct gives great failure messagesExpected: (a string containing "color" or a string containing "colour") Got: "Utter, complete and total darkness""
24
24
Find out more for yourselves
• Read this • https://github.com/junit-team/junit/wiki/Assertions
• Comprehensive example of assertions and matchers from JUnit and Hamcrest
• Follow these up if you want/need to • Timeouts for tests
https://github.com/junit-team/junit/wiki/Timeout-for-tests • Fixtures for tests in a class
(an ‘@Before’ for all tests in a class)https://github.com/junit-team/junit/wiki/Timeout-for-tests
• Running from the command line https://github.com/junit-team/junit/wiki/Test-runners
25
25
Finally, this may help you
26
Ignoring a test
• Put @Ignore on the line above @Test
27
27
Test cycle: Red, green, refactor
28
GREENRED
https://octoberclub.wordpress.com/2011/10/04/tidying-up-technical-debt-using-tdd/
28