PyCharm 2023.1 Help

Test your first Python application

Remember, in the first tutorial you’ve created your first Python application, and in the second tutorial you’ve debugged it. Now it’s time to do some testing. Let's modify the brake method of the code sample:

def brake(self): self.speed -= 5

Choosing the test runner

PyCharm auto-detects a test runner that is installed on your Python interpreter and uses it to run tests. If no specific test runner is installed, PyCharm uses unittest.

To explicitly set the required test runner in the project settings, press Control+Alt+S to open the IDE settings and select Tools | Python Integrated Tools, and then select the target test runner from the Default test runner list.

Selecting a test runner

For more details, see Testing frameworks.

Creating tests

A quick way to create tests is to have PyCharm stub them out from the class we’d like to test. To do this, we need to open Car.py, then right-click the name of the class, point to Go To, and then choose Test (or just press Control+Shift+T):

Go to test

A popup appears that suggests to create a new test:

Create a new test

OK, let’s do it. We are going to test whether our car is able to accelerate and brake, so let's select those checkboxes:

Create test dialog

A new Python test class is created:

test class

You can run the test by clicking the Run Run icon icon in the gutter near the class definition. A Run/Debug configuration will be created automatically:

Running a test from the context menu
However, we can see that the test fails by default:

Failed test

Now we know that we can run tests, let’s start writing some actual test code.

Writing tests

How to write unit tests is out of scope for this article. If you’re interested in learning about using the `unittest` framework, you can check out their docs.

For our example let’s use these tests:

import unittest from Car import Car class TestCar(unittest.TestCase): def setUp(self): self.car = Car() class TestInit(TestCar): def test_initial_speed(self): self.assertEqual(self.car.speed, 0) def test_initial_odometer(self): self.assertEqual(self.car.odometer, 0) def test_initial_time(self): self.assertEqual(self.car.time, 0) class TestAccelerate(TestCar): def test_accelerate_from_zero(self): self.car.accelerate() self.assertEqual(self.car.speed, 5) def test_multiple_accelerates(self): for _ in range(3): self.car.accelerate() self.assertEqual(self.car.speed, 15) class TestBrake(TestCar): def test_brake_once(self): self.car.accelerate() self.car.brake() self.assertEqual(self.car.speed, 0) def test_multiple_brakes(self): for _ in range(5): self.car.accelerate() for _ in range(3): self.car.brake() self.assertEqual(self.car.speed, 10) def test_should_not_allow_negative_speed(self): self.car.brake() self.assertEqual(self.car.speed, 0) def test_multiple_brakes_at_zero(self): for _ in range(3): self.car.brake() self.assertEqual(self.car.speed, 0) , ,

Running tests

Now let's run the tests. Right-click the test_Car.py editor tab and choose Run 'Unittests in test_Car.py':

Running unittests in a file

This time some tests pass successfully:

Run unittest

Debugging tests

Next, let's look deeper into the test code and debug one of the tests that failed. For example, we'll put a breakpoint in the following place:

Test breakpoint

Next, launch a debugger session. To do that, click Start debugger in the Navigation bar, or right-click the editor background at the method test_should_not_allow_negative_speed and choose Debug from the context menu:

Debug

We've placed the breakpoint at the self.car.brake() statement of the test_should_not_allow_negative_speed method. Let's look at the debugger output:

Debugging output

Click the Step into my code button to skip the library classes and go into the class Car:

Skip the library

Next, click the Step into my code button again, and see the test debug output:

Debugging output

It shows that speed can become negative, which is impossible. It seems that some additional code is required in the class Car.

Change the method brake as follows:

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

Now let's run the tests again. Switch to test_car.py and click the Run button in the Navigation bar:

Passing tests

All tests have passed.

Running tests automatically

In the last paragraph, after fixing our code, we reran our tests by using the the Run button button. If you'd like to focus on your code, and just see when you've resolved the issue, PyCharm can run the tests for you automatically.

Click the Run test automatically button on the Run toolbar. Then, every time you enter changes in your project files (as it was done earlier), the tests will run without your intervention.

Last modified: 03 May 2023