This rule raises an issue when the expected and actual values in an assertion appear to be inverted with respect to the testing framework’s convention.

Why is this an issue?

Assertions are statements that check whether certain conditions are true. They validate that the actual results of a code snippet match the expected outcomes. By using assertions, developers can ensure that their code behaves as intended and identify potential bugs or issues early in the development process.

Python testing frameworks follow a convention for where expected and actual values should appear in assertions:

In all of these assertion styles, the value produced by the code under test comes first and the expected value comes second. Keeping each value in the position expected by the assertion style makes the intent easier to understand and helps readers interpret failures more quickly.

Additionally, following each framework’s assertion conventions makes tests more consistent with the surrounding code and easier to read.

What is the potential impact?

Having the expected value and the actual value in the wrong order will not alter the outcome of tests (they will still succeed or fail appropriately). However, the error messages will contain misleading information, making debugging more difficult.

For example, if you write self.assertEqual(0, runner.exit_code) where runner.exit_code is -1, the failure is reported as 0 != -1. The message does not explicitly identify one value as expected and the other as actual, but following a consistent convention still makes assertions easier to read and understand.

How to fix it in unittest

Swap the order of the assertion arguments so that the actual value (from the code under test) is passed as the first argument and the expected value is passed as the second argument.

Code examples

Noncompliant code example

import unittest

class TestRunner(unittest.TestCase):
    def test_exit_code(self):
        runner = Runner()
        self.assertEqual(0, runner.exit_code, "Unexpected exit code")  # Noncompliant

Compliant solution

import unittest

class TestRunner(unittest.TestCase):
    def test_exit_code(self):
        runner = Runner()
        self.assertEqual(runner.exit_code, 0, "Unexpected exit code")

How to fix it in pytest

In pytest, place the actual value on the left side of the assertion and the expected value on the right side. The right-hand side should be limited to a literal or an identifier representing the expected value, including when using helpers such as pytest.approx(), rather than an expression that computes the value.

Code examples

Noncompliant code example

import pytest

EXPECTED_PI = 3.14

def test_calculation():
    result = perform_calculation()
    assert 3.14 == result  # Noncompliant
    assert pytest.approx(EXPECTED_PI) == result  # Noncompliant

Compliant solution

import pytest

EXPECTED_PI = 3.14

def test_calculation():
    result = perform_calculation()
    assert result == 3.14
    assert result == pytest.approx(EXPECTED_PI)

How to fix it in assertpy

In assertpy, place the actual value from the code under test in assert_that(…​) and pass the expected value to the assertion method.

Code examples

Noncompliant code example

from assertpy import assert_that

EXPECTED_EXIT_CODE = 0

def test_exit_code():
    runner = Runner()
    assert_that(EXPECTED_EXIT_CODE).is_equal_to(runner.exit_code)  # Noncompliant

Compliant solution

from assertpy import assert_that

EXPECTED_EXIT_CODE = 0

def test_exit_code():
    runner = Runner()
    assert_that(runner.exit_code).is_equal_to(EXPECTED_EXIT_CODE)

Resources

Documentation