JetBrains Fleet 1.44 Help

Using unittest

Prepare an example

Create a new file car.py and fill it with the following code. It defines the Car class which has two methods: accelerate and brake:

class Car: def __init__(self, speed=0): self.speed = speed def accelerate(self): self.speed += 5 def brake(self): self.speed -= 5

Now create test_car.py with the following code:

from unittest import TestCase from car import Car class TestCar(TestCase): car = Car(30) def test_accelerate(self): self.car.accelerate() self.assertEqual(self.car.speed, 35) def test_brake(self): self.car.brake() self.assertEqual(self.car.speed, 25)

Here we've imported the Car class from car.py, defined TestCar as a subclass of unittest.TestCase, and created an instance of Car with the initial speed 30. The test_accelerate and test_brake methods will test the respective methods of the Car class.

Run tests

If JetBrains Fleet is in Smart Mode, and a Python interpreter has been configured for the project workspace, you should see run icons in the gutter next to test methods definitions. You can use them to run each test individually:

Gutter icons for unittest tests

Alternatively, you can create a run configuration. Click the Run icon (⌘ R) and select Create Run Configurations in run.json.

A configuration for unittest must include "type": "python-tests" and "testFramework": "unittest". Also, specify the name of the file with tests in target:

{ "type": "python-tests", "name": "test_my_car", "testFramework": "unittest", "targets": ["test_car"], },

Run the configuration by pressing⌘ R. A terminal with the tests results will open:

Unittest results in terminal

Fix failing tests

test_brake has failed. Click it in the left pane to see the reason:

Failed test_brake method details

We assumed the car speed to be 25 after braking, but in fact it was 30. Why did that happen? The tests ran one after another, and the test_accelerate method had changed the initial speed of the car. To avoid this effect, let's implement a setUp() method to reinitialize the car before running each test:

from unittest import TestCase from car import Car class TestCar(TestCase): def setUp(self): self.car = Car(30) def test_accelerate(self): self.car.accelerate() self.assertEqual(self.car.speed, 35) def test_brake(self): self.car.brake() self.assertEqual(self.car.speed, 25)

Now rerun the test_my_car configuration and make sure that all tests have passed:

unittest passed all tests

Use tests to locate issues

Tests are designed to reveal problems in code. When you push the brake pedal in a real car it will either slow down or stop completely, depending on the initial speed. Let's check if the same is true for our Car class.

The following test uses subtests, add it to test_car.py:

class TestSpeeds(TestCase): def test_move(self): for s in range(0,101): with self.subTest(f"Braking from speed {s}"): self.car = Car(s) self.car.brake() distance = self.car.speed*1 self.assertTrue(distance >= 0)

This test runs 100 times with the speeds in the range from 0 to 100. At each speed, the car is braked, and then we calculate how far it will go with the new speed in one hour. That distance must be equal to or greater than zero.

Run the tests:

Results of a test with subtests

If you click one of the failed test_move tests, you'll see that it failed because the distance is negative.

Modify the brake method of the Car class to completely stop the car when its speed is 5 or less:

def brake(self): if self.speed <= 5: self.speed = 0 else: self.speed -= 5

Now all tests pass:

A test with subtests passed
Last modified: 11 February 2024