कमांड लाइन के माध्यम से unittest.TestCase से एकल परीक्षण चल रहा है


256

हमारी टीम में, हम इस तरह के अधिकांश परीक्षण मामलों को परिभाषित करते हैं:

एक "ढांचा" वर्ग ourtcfw.py:

import unittest

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

    # other stuff that we want to use everywhere

और 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()

जब मैं नया परीक्षण कोड लिख रहा हूं और इसे अक्सर चलाना चाहता हूं, और समय की बचत करता हूं, तो मैं क्या करता हूं कि मैंने अन्य सभी परीक्षणों के सामने "__" डाल दिया। लेकिन यह बोझिल है, मुझे लिखे गए कोड से विचलित करता है और यह जो शोर पैदा करता है वह सादा कष्टप्रद है।

इसलिए जैसे परिवर्तन करते समय testItIsHot(), मैं ऐसा करने में सक्षम होना चाहता हूं:

$ python testMyCase.py testItIsHot

और केवलunittest चलाए हैं testItIsHot()

मैं उसे कैसे प्राप्त कर सकता हूं?

मैंने if __name__ == "__main__":भाग को फिर से लिखने की कोशिश की , लेकिन जब से मैं पायथन के लिए नया हूं, तब से मैं खो गया महसूस कर रहा हूं और तरीकों के अलावा बाकी सभी चीजों को कोस रहा हूं।

जवाबों:


311

यह आपके सुझाव के अनुसार काम करता है - आपको बस कक्षा का नाम बताना होगा:

python testMyCase.py MyCase.testItIsHot

2
अरे बाप रे! चूँकि परीक्षण python2.6 पर चलाए जाने हैं (99% समय मैं खुद python2.7 के साथ परीक्षण का परीक्षण कर सकता हूं), मैं 2.6.8 डॉक्टर को देख रहा था और बहुत याद किया! :-)
एलोइस महदाल

1
बस ध्यान दिया जाता है कि यह केवल तभी काम करता है जब विधि को "परीक्षण *" कहा जाता है, इसलिए दुर्भाग्य से इसका उपयोग कभी-कभार परीक्षण चलाने के लिए नहीं किया जा सकता है जो कि नाम बदलकर "अक्षम" है
एलोइस महदाल

4
एक उपनिर्देशिका में परीक्षण के लिए काम नहीं करता है - एक परिपक्व पायथन कार्यक्रम में सबसे आम मामला।
टॉम स्विरली

4
@TomSwirly अब जांच नहीं कर सकता है, लेकिन मुझे लगता है कि आप इसे __init__.pyउस direcrory (और सबडिर, यदि कोई हो) के अंदर क्रिएट (खाली) कर सकते हैं और जैसे कॉलिंग कर सकते हैं। python test/testMyCase.py test.MyCase.testItIsHot
एलोइस महदाल

1
जब मैं ऐसा करता हूं तो कुछ नहीं होता है। मुझे वर्कअराउंड मिला, लेकिन मुझे उम्मीद थी कि यह विधि मेरे लिए काम करेगी।
जो फ्लाक

152

यदि आप अपने परीक्षण मामलों को व्यवस्थित करते हैं, अर्थात वास्तविक कोड की तरह ही संगठन का पालन करते हैं और उसी पैकेज में मॉड्यूल के लिए सापेक्ष आयात का भी उपयोग करते हैं

आप निम्न कमांड प्रारूप का उपयोग कर सकते हैं:

python -m unittest mypkg.tests.test_module.TestClass.test_method
# In your case, this would be:
python -m unittest testMyCase.MyCase.testItIsHot

इसके लिए Python3 दस्तावेज़ीकरण: https://docs.python.org/3/library/unittest.html#command-hi-face.com


यह बहुत अव्यवस्थित जावा-एस्क है। "long_module_name.SameLongNameAsAClass.test_long_name_beginning_with_test_as_a_conference" ... बेहतर आशा है कि आपने एक साने की तरह सुइट्स में संशोधन नहीं किया जो उनके कोड का परीक्षण करता है।
जोशुआ डेटेलर

69

यह आपके अनुमान के अनुसार अच्छा काम कर सकता है

python testMyCase.py MyCase.testItIsHot

और सिर्फ परीक्षण करने का एक और तरीका है testItIsHot:

    suite = unittest.TestSuite()
    suite.addTest(MyCase("testItIsHot"))
    runner = unittest.TextTestRunner()
    runner.run(suite)

11
मुझे इस उत्तर का दूसरा भाग बेहद मददगार लगा: मैं ग्रहण + प्यदेव में परीक्षण लिख रहा हूँ और मैं कमांड लाइन पर स्विच नहीं करना चाहता हूँ!
जियोवानी डी मिलिया

25

यदि आप unittest मॉड्यूल की सहायता से जांच करते हैं तो यह आपको कई संयोजनों के बारे में बताता है जो आपको एक परीक्षण केस क्लास से एक मॉड्यूल और परीक्षण विधियों से परीक्षण केस कक्षाएं चलाने की अनुमति देता है।

python3 -m unittest -h

[...]

Examples:
  python3 -m unittest test_module               - run tests from test_module
  python3 -m unittest module.TestClass          - run tests from module.TestClass
  python3 -m unittest module.Class.test_method  - run specified test method

इसके लिए आपको unittest.main()अपने मॉड्यूल के डिफ़ॉल्ट व्यवहार को परिभाषित करने की आवश्यकता नहीं है ।


2
+1 और शब्दावली के बाद से एक भाषा के लिए नया है, तो भ्रमित किया जा सकता है (और usageभी अजीब तरह से असंगत है): चल रहा है python -m unittest module_test.TestClass.test_methodएक फ़ाइल मान लिया गया है module_test.py(वर्तमान निर्देशिका से चलाया, और __init.py__है नहीं ) की आवश्यकता; और module_test.pyइसमें class TestClass(unittest.TestCase)...शामिल है def test_method(self,...)(यह मेरे लिए अजगर 2.7.13 पर भी काम करता है)
माइकल

10

हो सकता है, यह किसी के लिए मददगार हो। यदि आप विशिष्ट वर्ग से केवल परीक्षण चलाना चाहते हैं:

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

यह मेरे लिए अजगर 3.6 में काम करता है


3

@Yarkee से प्रेरित होकर मैंने इसे पहले से ही प्राप्त कोड में से कुछ के साथ जोड़ दिया। आप इसे run_unit_tests()कमांड लाइन का उपयोग करने की आवश्यकता के बिना फ़ंक्शन को कॉल करके , या केवल कमांड लाइन से कॉल करके किसी अन्य स्क्रिप्ट से भी कॉल कर सकते हैं python3 my_test_file.py

import my_test_file
my_test_file.run_unit_tests()

अफसोस की बात है कि यह केवल Python 3.3या बेहतर काम करता है :

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")

धावक कोड:

#! /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,
    ]

    # Comment all the tests names on this list, to run all Unit Tests
    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()

कोड को थोड़ा संपादित करते हुए, आप सभी इकाई परीक्षणों के साथ एक सरणी पास कर सकते हैं जिसे आप कॉल करना चाहते हैं:

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

    classes = \
    [
        LineBalancingUnitTests,
    ]

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

और दूसरी फाइल:

import my_test_file

# Comment all the tests names on this list, to run all Unit Tests
unit_tests_to_run = \
[
    "test_it_is_sunny",
    # "test_it_is_hot",
]

my_test_file.run_unit_tests( unit_tests_to_run )

वैकल्पिक रूप से, आप https://docs.python.org/3/library/unittest.html#load-tests-protocol का उपयोग कर सकते हैं और अपने परीक्षण मॉड्यूल / फ़ाइल पर निम्न विधि को परिभाषित कर सकते हैं :

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

    # To add a single test from this file
    suite.addTest( LineBalancingUnitTests( 'test_it_is_sunny' ) )

    # To add a single test class from this file
    suite.addTests( unittest.TestLoader().loadTestsFromTestCase( LineBalancingUnitTests ) )

    return suite

यदि आप निष्पादन को एक एकल परीक्षण फ़ाइल तक सीमित करना चाहते हैं, तो आपको परीक्षण खोज पैटर्न को केवल उस फ़ाइल पर सेट करने की आवश्यकता है जहां आपने load_tests()फ़ंक्शन को परिभाषित किया है।

#! /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() )

संदर्भ:

  1. जब स्क्रिप्ट में unittest मॉड्यूल होता है, तो sys.argv [1] के साथ समस्या
  2. क्या पायथन क्लास में सभी कार्यों को पूरा करने और निष्पादित करने का एक तरीका है?
  3. अजगर में एक वर्ग के सभी सदस्य चर पर पाशन

वैकल्पिक रूप से अंतिम मुख्य कार्यक्रम उदाहरण के लिए, मैं unittest.main()विधि के कार्यान्वयन को पढ़ने के बाद निम्नलिखित बदलाव के साथ आया :

  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() )

3

टीएल; डीआर : यह बहुत संभावना काम करेगा:

python mypkg/tests/test_module.py MyCase.testItIsHot

स्पष्टीकरण :

  • सुविधाजनक तरीका है

    python mypkg/tests/test_module.py MyCase.testItIsHot

    काम करेंगे अपनी अनिष्चित धारणा यह है कि आपके पास पहले से ही इस पारंपरिक कोड स्निपेट है (आमतौर पर आपकी परीक्षा फ़ाइल के अंत में)।

    if __name__ == "__main__":
        unittest.main()
  • असुविधाजनक रास्ता

    python -m unittest mypkg.tests.test_module.TestClass.test_method

    हमेशा if __name__ == "__main__": unittest.main()आपके टेस्ट सोर्स फाइल में उस कोड स्निपेट की आवश्यकता के बिना काम करेगा ।

तो दूसरा तरीका असुविधाजनक क्यों माना जाता है? क्योंकि यह एक लंबे, डॉट-सीमांकित पथ को हाथ से टाइप करने के लिए (_ अपने शरीर के किसी एक भाग को यहां डालें) में दर्द होगा । जबकि 1 विधि में, mypkg/tests/test_module.pyभाग ऑटो-पूरा किया जा सकता है, या तो एक आधुनिक शेल द्वारा, या आपके संपादक द्वारा।

पुनश्च: यदि आपको लगता है कि शरीर का हिस्सा आपकी कमर से नीचे है, तो आप एक प्रामाणिक व्यक्ति हैं। :-) मेरा कहने का अर्थ है "उंगली का जोड़"। बहुत अधिक टाइपिंग आपके जोड़ों के लिए बुरा होगा। ;-)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.