How to write python test

Юнит-тесты на Python: Быстрый старт

Юнит-тестирование кода является неотъемлемой частью жизненного цикла разработки программного обеспечения. Юнит-тесты также формируют основу для проведения регрессионного тестирования, то есть они гарантируют, что система будет вести себя согласно сценарию, когда добавятся новые функциональные возможности или изменятся существующие.

В этой статье я продемонстрирую основную идею юнит-тестирования на одном классе. На практике вам придется писать множество тестовых случаев, добавлять их в тестовый набор и запускать все вместе. Управление тест-кейсами мы рассмотрим в следующей статье.

Сегодня мы сосредоточимся на тестировании бэкенда. То есть разработчик реализовал некоторый проект согласно спецификациям (например, Calculator.py), а ваша задача состоит в том, чтобы убедиться, что разработанный код действительно им соответствует (например, с помощью TestCalculator.py ).

Предположим, что вы написали класс Calculator для выполнения основных вычислительных функций: сложения, вычитания, умножения и деления.

Код для этого здесь ( Calculator.py ):

#A simple calculator class Calculator: #empty constructor def __init__(self): pass #add method - given two numbers, return the addition def add(self, x1, x2): return x1 + x2 #multiply method - given two numbers, return the #multiplication of the two def multiply(self, x1, x2): return x1 * x2 #subtract method - given two numbers, return the value #of first value minus the second def subtract(self, x1, x2): return x1 - x2 #divide method - given two numbers, return the value #of first value divided by the second def divide(self, x1, x2): if x2 != 0: return x1/x2

Теперь я хочу запустить юнит-тест, чтобы понять, что функциональность в приведенном выше классе работает, как запланировано.

Обычно Python поставляется уже с пакетом unittest . Если в вашей системе его нет, используйте pip для его установки.

Читайте также:  Set textarea value with javascript

Юнит-тест имеет следующую структуру:

setUp() и tearDown() – это стандартные методы, которые поставляются с фреймворком unittest (они определены в классе unittest.TestCase). В зависимости от вашего тестового случая вы можете переопределять или не переопределять два этих метода по умолчанию.

Пришло время посмотреть на код тест-кейса. Вот файл TestCalculator.py .

import unittest from Calculator import Calculator #Test cases to test Calulator methods #You always create a child class derived from unittest.TestCase class TestCalculator(unittest.TestCase): #setUp method is overridden from the parent class TestCase def setUp(self): self.calculator = Calculator() #Each test method starts with the keyword test_ def test_add(self): self.assertEqual(self.calculator.add(4,7), 11) def test_subtract(self): self.assertEqual(self.calculator.subtract(10,5), 5) def test_multiply(self): self.assertEqual(self.calculator.multiply(3,7), 21) def test_divide(self): self.assertEqual(self.calculator.divide(10,2), 5) # Executing the tests in the above test case class if __name__ == "__main__": unittest.main()

Хотя это и не обязательно, но как правило я называю тестовый класс с префиксом Test (в нашем случае TestCalculator). Ключевым требованием в этом классе является наличие надкласса unittest.TestCase .

Всякий раз, когда выполняется этот тест-кейс, сначала выполняется метод setUp(). В нашем случае мы просто создаем объект класса Calculator и сохраняем его как атрибут класса. В родительском классе есть несколько других методов по умолчанию, которые мы рассмотрим позже.

На данный момент все, что вы будете делать, это писать методы test_xxx для тестирования каждого метода в классе Calculator. Обратите внимание, что все тестовые методы начинаются с префикса test_ . Это говорит Python с помощью фреймворка unittest, что это методы тестирования.

В каждом из методов тестирования я использовал встроенный метод assertEqual , чтобы проверить, возвращают ли методы калькулятора ожидаемое значение. Если возвращаемое значение равно ожидаемому значению, то тест проходит успешно, в противном случае он завершается неудачей.

Есть множество встроенных методов assert , о которых мы будем говорить позже.

Последняя строка в приведенном выше коде просто запускает тестовый случай TestCalculator . Он выполняет каждый тестовый метод, определенный внутри класса, и выдает результат.

python TestCalculator.py -v

Вы увидите вывод, сходный со следующим:

test_add (__main__.TestCalculator) . ok test_divide (__main__.TestCalculator) . ok test_multiply (__main__.TestCalculator) . ok test_subtract (__main__.TestCalculator) . ok -------------------------------------------------------------------- Ran 4 tests in 0.000s OK

Что делать, если что-то не работает, как ожидалось? Давайте изменим ожидаемое значение test_divide с 5 на 6 (5 – правильное значение, сейчас мы посмотрим, что случится при сбое. Это не ошибка в исходном коде, а ошибка в тестовом наборе, у вас тоже могут быть ошибки в тестовых наборах, поэтому всегда проверяйте тестовые сценарии на наличие ошибок!)

import unittest from Calculator import Calculator #Test cases to test Calulator methods #You always create a child class derived from unittest.TestCase class class TestCalculator(unittest.TestCase): #setUp method overridden from the parent class TestCase def setUp(self): self.calculator = Calculator() . def test_divide(self): self.assertEqual(self.calculator.divide(10,2), 6) # Executing the tests in the above test case class if __name__ == "__main__": unittest.main()

При запуске этого тест-кейса, вы получите следующий результат:

test_add (__main__.TestCalculator) . ok test_divide (__main__.TestCalculator) . FAIL test_multiply (__main__.TestCalculator) . ok test_subtract (__main__.TestCalculator) . ok ==================================================================== FAIL: test_divide (__main__.TestCalculator) -------------------------------------------------------------------- Traceback (most recent call last): File "TestCalculator.py", line 23, in test_divide self.assertEqual(self.calculator.divide(10,2), 6) AssertionError: 5.0 != 6 -------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (failures=1)

Здесь написано, что 3 из 4 тестов прошли успешно, а один не удался. В реальном сценарии, предполагается, что ваш тестовый случай является верным, то есть таким образом он помогает определять неправильно реализованную функцию.

Источник

Оцените статью