Homework required in preparation for this lecture
- Read Junit Tutorial and do the indicated steps.
- In addition add a method to MyClass and a test to MyClassTest. The method should throw an exception in some case, and the test should ensure that the exception was thrown, as expected.
- Deliverable: Upload your code to Github and do a Screencast. Include links in your homework log.
- Apply this to your product
- Isolate at least one class from your product. What I mean is to locate a class that does not depend on any other classes, or if necessary make a copy and modify it a little to remove such dependencies.
- Write a new class to use JUnit to test several of the methods of this class.
- Deliverable: Upload your code to Github and do a Screencast showing you running it, explaining any interesting bits. Include links in your homework log.
- (Extra Credit) Follow along this presentation: Embrace Unit Testing
- Deliverable: Write a blog post explaining exactly what a Mock is, when you would use it, and what the role of the Mock is on the code on slide 35 of the presentation is. You will need to do a little google research in addition to following the presentation.
- Learn about Testing
- What it is; why it is important; how we used to do it; automated testing
- The different kinds of testing - Unit, Integration, System testing.
- Tools used for automated testing
- xUnit - e.g. jUnit. How it works, what the assertions are
- What a test suite is
- The red/green/refactor cycle
- Tour of Eclipse features that support testing
- Automatic running of unit testing
- Refactoring commands
- Test Driven Development
- What it is, why it is important
- Discussion: What is a bug? (http://xkcd.com/327/)
- When you write a lot of code (100's, 1000's and 10K lines) you will have bugs, lots of bugs
- Bugs come back (regressions)
- Fixing one part can break another -- how do you find out? By running?
- By the way, complementary skills are as important:
- Learn to use the debugger - it is your friend!
- Learn to use logging effectively. Sometimes it's the only solution
- The role of a "spike" - plan to throw one out. Experiment. But then write good code
- We used to have separate QA then QE departments. Write test plans. Do manual testing, logging lots of bugs that way
- Nowadays there still is QA but they are much more integrated with the software engineers, sometimes there's no difference
- Test automation is considered a requirement for serious software engineering.
Different Kinds of Testing
- Unit testing: One 'unit' which usually means one class. Most easily and effectively automated
- Integration Testing: Testing the integration of a set of classes or subsystem. Still automatable, but more difficult
- System Testing: Most difficult to automate. Often involves 'simulated user'. But how do you deal with changes in UI?
- Testing can be done without tools
- JUnit is a simple tool to help you build suites of automated unit tests (in fact there are xUnit tools for many languages, as it is a pattern that has proven very successful.)
- Classic agile process is: test - red - green - refactor
Lets look at some code
- Super simple case: junittest
- Look at Testing of Tim's model in JBS2011-PA3 (see pito branch)
- Look at my experimentation with the gameoflifemodel
- Eclipse tools:
- Running tests
Test Driven Development
- Principle is: write tests first, before writing the code!!!
- Weird, eh?
- Write a test for the simplest case that could possibly work
- Instead of testing a GameBoard that is (100,100) start with one that is (1,1) and test whether you can store a single object in it
- Let's try a small case by hand. Look at MagicMath Class
- Would like to have it do arithmetic on String values, e.g. "1" + "2" returns 3
- And on words, e.g. "one" + "two" returns 3
- Let's write the tests first
- And now run them and fix the implementation
- Let's add a feature to Tim's JBS2011-PA3 (see pito branch)
- What feature should we add?
- Write test first, now let's write implementation
Rules of thumb
- Sometimes during testing you need to refactor the code or the test. This is good!
- How to handle classes which depend on others?
- First, it's good to avoid it if you can...
- Mocks are classes which 'stand in' for other classes.
- Take a look at Mockito
- Test Fixtures
- Fancy term for objects (data) needed before the test is even attempted
- The '@before' annotation is the simplest kind
- Sometimes the fixture is a data file on disk, or a database
- Note that tests MUST be independent of each other
- More modern Junit's actually run the tests in random order!
- Test Methods
- Make the Test Name meaningful. Not test1() but testAddingStringToString()
- Keep the test method as short as possible
- Make sure the test method tests ONE thing
- What to test
- Minimal cases: 0 by 0, one object, zero length string
- Typical cases
- Extreme cases that should work
- Other cases that should fail
- Review the code and decide what else could be tested
- Before fixing a bug
- Try to write a test that exercises the bug in isolation and add it to your test suite: RED
- Now fix the bug: GREEN
- If the bug ever comes back (regression) you will know!
SO: Try to get in the habit of writing even a few tests... It will pay off handsomely!