Unit Tests
“The Testing Pyramid,” unit tests verify how isolated parts of your application work. Before checking how things work together, you need to make sure the units of your application behave as expected.
you will Learn what unit tests are and what are the best places to use them.
? Write unit tests using the test-driven development (TDD) pattern to learn these concepts in the context of TDD.
When to use unit tests
Unit tests are the fastest and easiest tests to write. They also are the quickest to run. When you want to ensure that a class or method is working as intended in isolation — this means with no other dependent classes — you write unit tests.
Before writing any feature code, you should first write a unit test for one of the classes that will compose your feature. Afterwards, you write the class that will pass the test. After repeating this procedure, you’ll have a completed, testable feature
Creating unit tests
Running the test
the test will be failed.
Making the test pass
Now run the test again and see that it passes.
Creating more tests
The game will show a highest score. So, you should add a test that checks that when the current score is above the highest score, it increments the highest score:
@Test
fun whenIncrementingScore_aboveHighScore_shouldAlsoIncrementHighScore() {
val game = Game()
game.incrementScore()
Assert.assertEquals(1, game.highestScore)
}
Again if you try to compile it’ll fail because the highestScore property is missing. So, add the following property to the Game class:
var highestScore = 0
private set
Now the test will compile, so run it and watch it fail.
To make it pass, open the Game class and modify the incrementScore() method as follows:
Run the test and you’ll see that it passes
However, you should also test that, when the highest score is greater than the current score, incrementing the current score won’t also increment the highest score, so add the following test:
Here, the intention is to create a Game with a highscore of 10. The test won’t compile because you need to modify the constructor to allow a parameter. Because you need to start with a highest score greater than the default, which is 0, you need to alter the constructor like this:
Now, run all the tests and see that the last one doesn’t pass. You can use the green arrow button on the left-side of the class definition.
The last one doesn’t pass because you’re incrementing both the current score and highest score regardless of their values. Fix that by replacing the incrementScore() function with the following:
Build and run the last test to see the satisfying green checkmark.
Now I will add questions to make trivia game:
so you’ll now create unit tests that model a question with two possible answers. The question also has an “answered” option to model what the user has answered to the question
领英推荐
@Test
fun whenCreatingQuestion_shouldNotHaveAnsweredOption() {
val question = Question("CORRECT", "INCORRECT")
Assert.assertNull(question.answeredOption)
}
Here, you used assertNull to check if question.answeredOption is null. If you try to run this test it won’t compile because the Question class doesn’t exist.
Create the Question class:
class Question(val correctOption: String,
val incorrectOption: String) {
var answeredOption: String? = null
private set
}
Run the test again and watch that it now passes.
Now, you can add another test:
@Test
fun whenAnswering_shouldHaveAnsweredOption() {
val question = Question("CORRECT", "INCORRECT")
question.answer("INCORRECT")
Assert.assertEquals("INCORRECT", question.answeredOption)
}
This test will check that, when you add the user’s answer to a question, the user’s answer is saved in the answeredOption property. You’ll get a compilation error since you haven’t written the answer() method yet.
Add the following to the Question class to make it compile:
fun answer(option: String) { // No implementation yet }
Now run the test and you’ll see that it doesn’t pass.
fun answer(option: String) {
answeredOption = option
}
Because you’ll need to know if the question was answered correctly, imagine that the answer() method now returns a Boolean. The result would be true when the user answered correctly. Now, add this test.
@Test
fun whenAnswering_withCorrectOption_shouldReturnTrue() {
val question = Question("CORRECT", "INCORRECT")
val result = question.answer("CORRECT")
Assert.assertTrue(result)
}
Notice, here, that you’re using assertTrue. It checks for a Boolean result. Running this test will get you a compilation error since the answer() method doesn’t return a Boolean. Update the Question class so that the answer() method returns a Boolean.For now, always return false
fun answer(option: String): Boolean {
answeredOption = option
return false
}
Run it and watch it fail.
Fix it temporarily by always returning true:
fun answer(option: String): Boolean {
answeredOption = option
return true
}
Run it and watch it pass.
Add the following test:
@Test fun whenAnswering_withIncorrectOption_shouldReturnFalse() {
val question = Question("CORRECT", "INCORRECT")
val result = question.answer("INCORRECT")
Assert.assertFalse(result)
}
Run it and see that it fails.
Now that we have tests for when the answer is correct and when the answer is not correct, we can fix the code:
fun answer(option: String): Boolean {
answeredOption = option
return correctOption == answeredOption
}
Run all the Question tests and verify they all pass correctly.
Finally, you should ensure that the answer() method only allows valid options. Add this test
@Test(expected = IllegalArgumentException::class)
fun whenAnswering_withInvalidOption_shouldThrowException() {
val question = Question("CORRECT", "INCORRECT")
question.answer("INVALID")
}
Notice, here, that the @Test annotation allows to expect an exception. If that exception occurs, the test will pass. This will save you from writing try/catch. If you run the test now, it will fail because the answer() method doesn’t throw the exception.
To fix this, modify the Question class as follows:
Run the test and watch that it now passes.
Refactoring the unit tests:
*)QuestionClass
*)QuestionClassUnitTests
Senior Android Developer at Awqaf
11 个月?????????? ?? ?????
Software Engineer| Junior Android Developer Kotlin & Java | Freelance Professional Open for Opportunities
11 个月???? ??? ???? ????? ???? ??
Service Engineer
11 个月Good job ??
Mobile Developer ( Native Android & Flutter )
11 个月???? ???? ????? ????? ??
Front End Developer React& Next JS | Bubble.io Developer
11 个月????? ???? ??? ????? ??