386 Stimmen

Einen einzelnen Test von unittest.TestCase über die Befehlszeile ausführen

In unserem Team definieren wir die meisten Testfälle wie folgt:

Eine "Framework" Klasse ourtcfw.py:

import unittest

class OurTcFw(unittest.TestCase):
    def setUp:
        # Etwas

    # Anderes Zeug, das wir überall verwenden wollen

Und viele Testfälle wie testMyCase.py:

import localweather

class MyCase(OurTcFw):

    def testItIsSunny(self):
        self.assertTrue(localweather.sunny)

    def testItIsHot(self):
        self.assertTrue(localweather.temperature > 20)

if __name__ == "__main__":
    unittest.main()

Wenn ich neuen Testcode schreibe und ihn oft ausführen und Zeit sparen möchte, füge ich "__" vor allen anderen Tests ein. Aber das ist umständlich, lenkt mich vom Code ab, den ich schreibe, und der Commit-Lärm, den dies verursacht, ist einfach nur nervig.

Also, wenn ich Änderungen an testItIsHot() vornehme, möchte ich in der Lage sein, dies zu tun:

$ python testMyCase.py testItIsHot

und lassen unittest nur testItIsHot() ausführen

Wie kann ich das erreichen?

Ich habe versucht, den if __name__ == "__main__": Teil umzuschreiben, aber da ich neu in Python bin, fühle ich mich verloren und stoße ständig auf alles andere als die Methoden.

19voto

Bohdan Punkte 191

Wenn Sie nur Tests aus einer bestimmten Klasse ausführen möchten:

if __name__ == "__main__":
    unittest.main(MyCase())

Es funktioniert bei mir in Python 3.6.

11voto

Rodolfo Ortega Punkte 377

Was für mich funktioniert hat, war:

cd Projektverzeichnis
python -m unittest -v Pfad\zu\test\testMyCase.py -k my_test_name

-v steht für detaillierte Unittest-Protokollausgabe.

8voto

ronkov Punkte 1033

Wenn Sie den Test direkt aus einem Skript ausführen möchten (zum Beispiel aus einem Jupyter Notebook), können Sie dies tun, um nur einen Test auszuführen:

from testMyCase import MyCase
unittest.main(argv=['ignored', '-v', 'MyCase.testItIsHot'], exit=False)

4voto

user Punkte 7158

Angeregt durch yarkee, kombinierte ich es mit einigem der Code, den ich bereits hatte. Sie können dies auch von einem anderen Skript aus aufrufen, indem Sie einfach die Funktion run_unit_tests() aufrufen, ohne den Befehlszeile zu verwenden, oder rufen Sie es einfach von der Befehlszeile aus mit python3 my_test_file.py.

import my_test_file
my_test_file.run_unit_tests()

Leider funktioniert dies nur für Python 3.3 oder höher:

import unittest

class LineBalancingUnitTests(unittest.TestCase):

    @classmethod
    def setUp(self):
        self.maxDiff = None

    def test_it_is_sunny(self):
        self.assertTrue("a" == "a")

    def test_it_is_hot(self):
        self.assertTrue("a" != "b")

Runner-Code:

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import unittest
from .somewhere import LineBalancingUnitTests

def create_suite(classes, unit_tests_to_run):
    suite = unittest.TestSuite()
    unit_tests_to_run_count = len( unit_tests_to_run )

    for _class in classes:
        _object = _class()
        for function_name in dir( _object ):
            if function_name.lower().startswith( "test" ):
                if unit_tests_to_run_count > 0 \
                        and function_name not in unit_tests_to_run:
                    continue
                suite.addTest( _class( function_name ) )
    return suite

def run_unit_tests():
    runner = unittest.TextTestRunner()
    classes =  [
        LineBalancingUnitTests,
    ]

    # Kommentiere alle Testnamen in dieser Liste aus, um alle Unit-Tests durchzuführen
    unit_tests_to_run =  [
        "test_it_is_sunny",
        # "test_it_is_hot",
    ]
    runner.run( create_suite( classes, unit_tests_to_run ) )

if __name__ == "__main__":
    print( "\n\n" )
    run_unit_tests()

Wenn Sie den Code ein wenig bearbeiten, können Sie ein Array mit allen zu aufrufenden Unit-Tests übergeben:

...
def run_unit_tests(unit_tests_to_run):
    runner = unittest.TextTestRunner()

    classes = \
    [
        LineBalancingUnitTests,
    ]

    runner.run( suite( classes, unit_tests_to_run ) )
...

Und eine andere Datei:

import my_test_file

# Kommentiere alle Testnamen in dieser Liste aus, um alle Unit-Tests durchzuführen
unit_tests_to_run = \
[
    "test_it_is_sunny",
    # "test_it_is_hot",
]

my_test_file.run_unit_tests( unit_tests_to_run )

Alternativ können Sie das load_tests-Protokoll verwenden und die folgende Methode in Ihrem Testmodul/-datei definieren:

def load_tests(loader, standard_tests, pattern):
    suite = unittest.TestSuite()

    # Um einen einzelnen Test aus dieser Datei hinzuzufügen
    suite.addTest( LineBalancingUnitTests( 'test_it_is_sunny' ) )

    # Um eine einzelne Testklasse aus dieser Datei hinzuzufügen
    suite.addTests( unittest.TestLoader().loadTestsFromTestCase( LineBalancingUnitTests ) )

    return suite

Wenn Sie die Ausführung auf eine einzige Testdatei beschränken möchten, müssen Sie nur das Test-Discovery-Muster auf die einzige Datei setzen, in der Sie die load_tests()-Funktion definiert haben.

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import unittest

test_pattern = 'mytest/module/name.py'
PACKAGE_ROOT_DIRECTORY = os.path.dirname( os.path.realpath( __file__ ) )

loader = unittest.TestLoader()
start_dir = os.path.join( PACKAGE_ROOT_DIRECTORY, 'testing' )

suite = loader.discover( start_dir, test_pattern )
runner = unittest.TextTestRunner( verbosity=2 )
results = runner.run( suite )

print( "results: %s" % results )
print( "results.wasSuccessful: %s" % results.wasSuccessful() )

sys.exit( not results.wasSuccessful() )

Referenzen:

  1. Problem mit sys.argv[1] wenn das unittest-Modul in einem Skript ist
  2. Gibt es einen Weg, um alle Funktionen in einer Python-Klasse zu durchlaufen und auszuführen?
  3. Durchlaufen aller Member-Variablen einer Klasse in Python

Alternativ zum letzten Hauptprogramm-Beispiel kam ich nach der Lektüre der unittest.main()-Methodenimplementierung auf folgende Variation:

  1. https://github.com/python/cpython/blob/master/Lib/unittest/main.py#L65

    ! /usr/bin/env python3

    -- coding: utf-8 --

    import os import sys import unittest

    PACKAGE_ROOT_DIRECTORY = os.path.dirname( os.path.realpath( file ) ) start_dir = os.path.join( PACKAGE_ROOT_DIRECTORY, 'testing' )

    from testing_package import main_unit_tests_module testNames = ["TestCaseClassName.test_nameHelloWorld"]

    loader = unittest.TestLoader() suite = loader.loadTestsFromNames( testNames, main_unit_tests_module )

    runner = unittest.TextTestRunner(verbosity=2) results = runner.run( suite )

    print( "results: %s" % results ) print( "results.wasSuccessful: %s" % results.wasSuccessful() ) sys.exit( not results.wasSuccessful() )

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X