NUnit - повторить тестовый случай 3 раза, если он не пройден - PullRequest
9 голосов
/ 09 августа 2011

У меня есть несколько тестов для автоматизации пользовательского интерфейса веб-сайта.

Я хочу попробовать мой тестовый пример, по крайней мере, три раза, если он не пройдёт первый и второй раз Таким образом, я хочу убедиться, что этот тестовый пример последовательно терпит неудачу.

Пожалуйста, дайте мне знать, если у нас есть возможность использовать в NUnit. Я использую C # с NUnit.

Ответы [ 6 ]

26 голосов
/ 06 марта 2012

Вы можете добавить новый атрибут в nunit на основе атрибута repeat и перестроить библиотеку. Это очень просто.

   [Test]
   [Repeat( 25 )]
   public void MyTest( ){
      // your test logic here
   }
7 голосов
/ 20 сентября 2016

Начиная с NUnit 3.0, есть атрибут 'Retry', который выглядит так, как будто он будет делать то, что хочет kumar.

См. Атрибут повтора

4 голосов
/ 09 августа 2011

Для зацикливания логики подсчитайте ошибки. Утверждение. (Ошибка == 0) Бум завершен.

Я бы посоветовал вам не делать этого. Напишите лучший тест, который вы можете доказать

2 голосов
/ 09 августа 2011

Существует 4 исключения, которые nunit использует, чтобы сообщить результат теста. Это TimeoutException, AssertException, SuccessException и IgnoreException. Вы можете использовать их в своих тестовых функциях. Я полагаю, вы можете поместить свой тестовый код в try-catch и поймать исключение nunit assert ровно дважды. Но я должен сказать, как отмечалось ранее, необходимость периодически проваливающегося теста является причиной для переосмысления.

0 голосов
/ 22 апреля 2019

Я создал скрипт-обёртку для nunit3-console в python, который запускает скрипт и, если есть какие-либо неудачные тесты, повторно запускает неудачные тесты до --max-retries раз. Это также объединит новые результаты с исходными TestResult.xml.

Сценарий называется nunit-repeat и размещен на https://github.com/sashoalm/nunit-repeat/.

Пример использования:

python nunit-repeat.py --max-retries 3 -- .\MockFailingTests\packages\NUnit.ConsoleRunner.3.10.0\tools\nunit3-console.exe .\MockFailingTests\MockFailingTests\bin\Debug\MockFailingTests.dll

Код:

# Script to run nunit tests and then repeat any failed tests until we run out of retries.

import os
import sys
import subprocess
import xml.etree.ElementTree as ET

# Finds the corresponding test with the same name in another XML file.
def findCorrespondingTest(tree2, failedTest):
    test2 = tree2.findall(".//test-case[@fullname='{}']".format(failedTest.get('fullname')))
    if len(test2) != 1:
        print(failedTest.get('fullname'))
        for ii in test2:
            print(ii.get('fullname'))
        raise Exception("len(test2) != 1")
    return test2[0]

# Python XML lib doesn't show you who is the parent of a given element so we add the info ourselves.
def addParentInfo(tree):
    for child in tree:
        setParent(child, tree)
        addParentInfo(child)

# We strip the parentage info so it doesn't pollute the XML file.
def stripParentInfo(tree):
    for child in tree:
        child.attrib.pop('__my_parent__', 'None')
        stripParentInfo(child)

# Gets the parent of a given element.
def getParent(tree):
    return tree.attrib['__my_parent__']

# Sets the parent of a given element.
def setParent(tree, parent):
    tree.attrib['__my_parent__'] = parent

# Updates a parent test suite of a failed test that has passed on rerun.
def updateTestSuite(tree):
    tree.attrib['failed'] = str(int(tree.attrib['failed']) - 1)
    tree.attrib['passed'] = str(int(tree.attrib['passed']) + 1)
    if tree.attrib['failed'] == '0':
        tree.attrib['result'] = 'Passed'

# In-place replaces a failed test with a successful one.
def replaceTest(tree1, tree2):
    parent = getParent(tree1)
    tree1.__setstate__(tree2.__getstate__())
    setParent(tree1, parent)

# Updates the entire chain of parent test suites.
def updateParentTestSuites(testCase):
    suite = getParent(testCase)
    while suite and suite.tag == 'test-suite':
        updateTestSuite(suite)
        suite = getParent(suite)

# Merges the results from a rerun into the original test.
# Any failed test that has become successful upon rerun is updated.
def mergeRerunResults(tree1, tree2):
    for failedTest in tree1.iterfind(".//test-case[@result='Failed']"):
        test2 = findCorrespondingTest(tree2, failedTest)
        if test2.attrib['result'] == 'Passed':
            replaceTest(failedTest, test2)
            updateParentTestSuites(failedTest)

# Checks whether we have any failed tests.
def hasFailedTests(tree):
    return len(tree.findall(".//test-case[@result='Failed']")) > 0

# Writes the failed tests, one per line, in testlist.txt. This file
# will be passed to nunit console runner.
def writeFailedTests(tree):
    f = open('testlist.txt', 'w')
    for failedTest in tree.iterfind(".//test-case[@result='Failed']"):
        name = failedTest.attrib['fullname']
        f.write(name + '\n')

# Retries all the failing tests, until all pass or we run out of retries.
def retryFailedTests(args, retries):
    # Add the testfilter to nunit's command line.
    args.append('--testlist')
    args.append('testlist.txt')
    # Load the test results from the first invocation.
    tree = ET.parse('TestResult.xml')
    addParentInfo(tree.getroot())
    # Run the retries.
    while retries > 0 and hasFailedTests(tree):
        retries -= 1
        writeFailedTests(tree)
        subprocess.call(args)
        mergeRerunResults(tree, ET.parse('TestResult.xml'))
    # Write the final results.
    stripParentInfo(tree.getroot())
    tree.write('TestResult.xml')
    # Check if we still have failing tests.
    if hasFailedTests(tree):
        raise Exception("There are failed tests even after retrying.")

# Main function.
def main():
    args = sys.argv
    # Get the number of retries.
    try:
        retries = int(args[args.index('--max-retries') + 1])
    except:
        retries = 3
    # Get the nunit command line.
    args = args[args.index('--')+1:]
    # Invoke nunit the first time.
    subprocess.call(args)
    # Retry any failed tests.
    retryFailedTests(args, retries)

# Execute main function.
main()
0 голосов
/ 19 мая 2018

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

[Test]
[Retry(3)]
public void MyTest( ){
  // your test logic here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...