Как запустить несколько тестовых примеров Python в цикле?

Я новичок в Python и пытаюсь делать то, что часто делаю на Ruby. А именно, перебор набора индексов, использование их в качестве аргумента функции и сравнение ее результатов с массивом выходных данных фикстуры.

Поэтому я написал это, как обычно, в Ruby, но в результате получился всего один тестовый пример.

  def test_output(self):
    for i in range(1,11):
      ....
      self.assertEqual(fn(i),output[i])

Я пытаюсь пройти тест для каждого предмета в ассортименте. Как я могу это сделать?


person picardo    schedule 28.09.2013    source источник
comment
Вы хотите создать 10 различных тестовых случаев? Показанный вами код работает, он просто выполняет все десять утверждений в одном тестовом примере.   -  person    schedule 29.09.2013


Ответы (4)


Используя unittest, вы можете показать разницу между двумя последовательностями в одном тестовом примере.

seq1 = range(1, 11)
seq2 = (fn(j) for j in seq1)
assertSequenceEqual(seq1, seq2)

Если это недостаточно гибко, с помощью unittest можно сгенерировать несколько тестов, но это немного сложно.

def fn(i): ...
output = ...

class TestSequence(unittest.TestCase):
    pass

for i in range(1,11):
    testmethodname = 'test_fn_{0}'.format(i)
    testmethod = lambda self: self.assertEqual(fn(i), output[i])
    setattr(TestSequence, testmethodname, testmethod)

Nose упрощает описанное выше с помощью генераторов тестов.

import nose.tools

def test_fn():
    for i in range(1, 11):
        yield nose.tools.assert_equals, output[i], fn(i)

Похожие вопросы:

person Trevor Merrifield    schedule 28.09.2013
comment
В этом есть смысл, спасибо за объяснение. Я займусь обновлением. - person Trevor Merrifield; 29.09.2013
comment
Вероятно, не следует помещать создание тестового метода в предложение if name == 'main', потому что оно изменяет модуль. Код тестовой последовательности не имеет смысла без кода генерации. - person Jappie Kerk; 25.01.2018

Начиная с Python 3.4, это можно сделать так:

def test_output(self):
    for i in range(1,11):
        with self.subTest(i=i):
            ....
            self.assertEqual(fn(i),output[i])

https://docs.python.org/3.4/library/unittest.html?highlight=subtest#distinguishing-test-iterations-using-subtests.

person Antoine Fontaine    schedule 28.06.2016
comment
@picardo: Пожалуйста, подумайте о том, чтобы принять этот ответ, а не принятый в настоящее время, чтобы другие люди не запутались в том, каким должен быть стандартный подход. - person ccpizza; 26.07.2020
comment
Это кажется очень элегантным ответом, но, к сожалению (насколько мне известно), методы setUp и tearDown не вызываются автоматически до и после каждого подтеста. Было бы неплохо узнать, есть ли способ вызывать setUp и tearDown до и после каждого подтеста, не делая этого явно. - person Kevin Südmersen; 22.01.2021
comment
@ KevinSüdmersen, это правда, setUp и tearDown не выполняются для каждого подтеста, так что это не серебряная пуля. - person Antoine Fontaine; 25.01.2021

В мире Python два самых популярных варианта написания тестов:

В pytest вы очень легко параметризуете тесты:

@pytest.mark.parametrize(('param1', 'param2'),[
                         (1, 'go'),
                         (2, 'do not go')])
def test_me(param1, param2):
    # write test

Это даст хороший результат также при запуске тестов:

go.py:2: test_me[1-go] PASSED
go.py:2: test_me[2-do not go] PASSED

Я использую pytest уже два года, и это очень хороший инструмент. У вас там много возможностей. Помимо параметризации, есть также фикстуры, очень-очень хорошие утверждения (вам не нужно писать assertEqual, просто assert a==b и pytest может сгенерировать для него очень хороший и полезный вывод.)

person spinus    schedule 28.09.2013
comment
pypi.org/project/parameterized - похоже, что функция была извлечена и может использоваться вне pytest в выполнить любую параметризацию. - person spinus; 21.02.2019

Если ваш вопрос касается того, когда вы решаете проблему на конкурентных местах, таких как хакерранк или где-то еще. Если они не предоставили свою среду для выполнения тестовых примеров в цикле.

И локально, если вы запускаете код для компилятора python, это было бы полезно.

вы можете просто использовать цикл while или функцию диапазона Python.

e.g:

t = int(input("Enter Number of testcases"))
type(t)

while(t!=0):

    n = int(input("Enter number of data"))
    type(n)

    // Code logic or function Call

    t = t-1
person Sourav Choudhary    schedule 24.08.2018