1 of 12

How do you measure code coverage & test well?

https://bit.ly/2OPrBS5

2 of 12

We saw last week: Testing is important

  • Hundreds of people telling you that you suck is sad
  • Getting a bad grade in phase 2 because you had bad tests is also sad (I suspect that’s why some of you are here. Welcome!)
  • I don’t want you to be sad!

3 of 12

Improvements to our MVC app

  • Since last week I’ve made some improvements to the MVC app.
  • In particular, i’ve added a new command “cd”, and made the project use Gradle and JUnit and include code coverage
  • Let’s talk about that!

4 of 12

Improving our app: Gradle

  • You’ve probably seen “gradle” thrown about everywhere, but I doubt you’ve all had a chance to understand exactly what it does…
  • Gradle is just a command that lets you run “tasks”
  • For example, “gradle build” will build your (android) app
  • “gradle test” runs the “test” task and searches in src/test/java/(package) for “Test” files
  • Generally all you need to edit to add libraries, test frameworks, code coverage plugins, … is to google “gradle (blah)” and then edit your “build.gradle” file
  • In Android, it will be in the app/ folder.

See the commit that adds gradle to MVCExample on github here

5 of 12

Improving our app: Gradle

  • Gradle generally allows different tools to all understand how your code works
  • For example, last week I was having trouble because intellij was confused about my project that I had created using a text editor
  • After I gradle-ized my project, I could just “import using existing model” -> “gradle” in IntelliJ and now everything works perfectly!
  • This is because IntelliJ knows exactly how gradle behaves, so it can understand exactly where my source/test/… files are, how libraries are set up, et cetera.

See the commit that adds gradle to MVCExample on github here

6 of 12

Improving our app: JUnit

  • There are very few libraries that have become so ingrained with a specific programming language as JUnit and Java.
  • If you write *any* tests (unit or otherwise), you’ll probably be using JUnit in some form or another.
  • In particular, the “@Test” annotation is a JUnit phenomenon.
  • The major benefit to using JUnit is that you can say things run before every test (@Before), after every test (@After), and see test results in android studio very easily.

See the commit that adds JUnit to MVCExample on github here

7 of 12

Code coverage

  • By now, you’ve maybe heard of “code coverage”
  • Code coverage is just how many lines of code are executed by *some* test or another
  • In particular, this means that code coverage of 100% means that you have some test that at least executes 100% of the code
  • This does *not*, however, mean that you have caught 100% of the bugs

8 of 12

Code coverage 2: Tricksy students

  • In CSC207, we’ve been testing code coverage for years now.
  • A common thing that comes up almost every year is people making integration tests to increase their code coverage.
  • If you run your app & click around, you will likely be running >75% of your code without really testing anything
  • That means that a “test” that runs a “main” method without *any* asserts will improve your code coverage by 75% without actually doing anything!
  • Do not do this.

9 of 12

Code coverage 3: How to actually do it

  • Remember that each test has an “assert” to get you to say something about how your code should actually behave
  • It’s easy to write unit tests if you follow SOLID & use MVC
  • Simply write a unit test for each class (*), mock the dependencies, & you can get 100% code coverage in that class!
  • It’s fine to ignore code coverage for model, view, and the “main” method within reason
  • Keep your main method small! It should only contain glue between the model, view, and controller, and be <10 lines.

* - only “controller” classes, not model / view!

10 of 12

The model: Beans / POJO

  • Java uses terms that nobody ever teaches you
  • “beans” and “POJOs”
  • “POJOs” are just classes that only contain a constructor, getters, and setters
  • That is, they don’t contain any logic (they are just that, POJO: Plain ol’ java objects)
  • “Java beans” are POJOS that are also Serializable & have getters / setters on every field
  • You don’t need to write unit tests for beans / pojos! This is silly!

11 of 12

Improving our tests with Mockito

There are a few problems with our existing test approach

  • If Terminal or Filesystem had 40 methods, it would be hard to tell if we were mocking them all (we generally don’t want them doing stuff unless we know what it is, otherwise we’ve written an integration test)
  • It’s generally pretty painful to keep track of “whatWasPrinted”, …
  • Our error messages are also bad -- all we get is a line number
  • Luckily, if we rewrite everything using JUnit and Mockito, our lives are better!

See the commit that adds mockito here

12 of 12

Code coverage 4: See your code coverage

  • In my MVC example, I’ve added instructions for setting up code coverage
  • Let’s see what that looks like!