Python has evolved a broad ecosystem that enables Python ProgrammerLife has become simpler and less repetitive in their work of making rounds. The same philosophy applies to the work of tool developers, even if the tools they develop do not appear in the final program. This article introduces the developer tools that Python programmers must know about.
The most practical help for developers is to help them write code documents. The pydoc module generates well-formed documents for any import module based on docstrings in the source code. Python contains two test frameworks to automatically test the code and verify the correctness of the Code: 1) Thedoctest module, which extracts test cases from the source code or the standalone file example. 2)unittest module, the module is a fully functional automated testing framework that provides test preparation (testing fixtures), predefined test sets (predefined test suite), and test discovery Discovery) Support.
The
trace module monitors how Python executes the program and generates a report that shows the number of times each line of the program is executed. This information can be used to discover the program execution path that is not covered by the automated test set, or to study the program call graph to discover dependencies between modules. Writing and executing tests can uncover problems in most programs, and Python makes debugging easier because, in most cases, Python can print unhandled errors to the console, which we call the error message traceback. If the program is not running in the text console, Traceback can also output the error message to a log file or to a message dialog box. When the standard traceback cannot provide enough information, you can use the Cgit B module to view detailed information in the stack and source code context, such as local variables. The CGITB module can also output these trace information as HTML to report errors in Web apps.
Once you find out where the problem is, you need to use the interactive debugger to get into the code for debugging, and thePDB module is well-suited to the job. The module can show the execution path of the program when the error occurs, and can dynamically adjust the object and code for debugging. When the program passes testing and debugging, the next step is to focus on performance. Developers can use the profile and the timit module to test the speed of the program, find out where in the program is very slow, and then work on this part of the code independently for tuning. The Python program is executed by the interpreter, and the input to the interpreter is the bytecode compiled version of the original program. This bytecode-compiled version can be generated dynamically when the program executes, or it can be generated when the program is packaged. The compileall module can handle the packaging of a program, exposing a packaging-related interface that can be used by installers and packaging tools to generate files containing module bytecode. Also, in the development environment, the Compileall module can be used to verify that the source file contains syntax errors.
At the source level, thePYCLBR module provides a class viewer that allows a text editor or other program to scan interesting characters in a Python program, such as a function or a class. After the class viewer is provided, there is no need to introduce code, which avoids the potential side effects.
Document strings and doctest modules
If a function, class, or the first line of a module is a string, then the string is a document string. It is considered a good programming practice to include a document string, because these strings can provide some information to Python program development tools. For example, the Help() command detects a document string, and the python-related IDE is able to work with the document string. Because programmers tend to view document strings in an interactive shell, it's a good idea to write these strings briefly. For example
# Mult.pyclass Test: "" " >>> a=test (5) >>> a.multiply_by_2 ()" "" def _ _init__ (self, number): self._number=number def multiply_by_2 (self): return self._number*2
A common question when writing a document is how to keep the document and the actual code in sync. For example, a programmer might modify the implementation of a function, but forget to update the document. For this problem, we can use the Doctest module. The Doctest module collects the document strings, scans them, and then executes them as tests. In order to use the Doctest module, we will typically create a separate module for testing. For example, if the previous example test class is contained in the file mult.py , then you should create a new testmult.py file to test as follows:
# Testmult.pyimport Mult, Doctestdoctest.testmod (mult, verbose=true) # trying:# a=test (5) # expecting nothing# ok# trying:# a.multiply_by_2 () # expecting:# 10# ok# 3 items had no tests:# mult# mult.test.__init__# Mult. test.multiply_by_2# 1 Items passed all tests:# 2 tests in mult. test# 2 Tests in 4 items.# 2 passed and 0 failed.# Test passed.
In this code,doctest.testmod (module) executes tests for a specific module and returns the number of failed tests and the total number of tests. If all the tests pass, then no output will be produced. Otherwise, you will see a failure report that shows the difference between expected and actual values. If you want to see the detailed output of the test, you can use testmod (module, verbose=true).
If you do not want to create a separate test file, then the other option is to include the appropriate test code at the end of the file:
if __name__ = = ' __main__ ': import doctest doctest.testmod ()
If you want to perform such tests, we can invoke the Doctest module with the-M option. Generally speaking, there is no output when the test is executed. If you want to see more information, you can add the-v option.
$ python-m doctest-v mult.py
Unit Test and unittest module
If you want to test the program more thoroughly, we can use the UnitTest module. With unit testing, developers can write a series of independent test cases for each element that makes up a program (for example, independent functions, methods, classes, and modules). When testing a larger program, these tests can be used as a cornerstone to verify the correctness of the program. As our programs get bigger and larger, unit tests on different components can be combined to become larger test frameworks and test tools. This greatly simplifies the work of software testing and facilitates the search and resolution of software problems.
# Splitter.pyimport Unittestdef Split (line, Types=none, Delimiter=none): "" "splits a line of text and optionally perfor MS type conversion. ... "" "Fields = Line.split (delimiter) If types:fields = [Ty (val) to Ty,val in Zip (types,fields)] return F Ieldsclass testsplitfunction (unittest. TestCase): def setUp (self): # Perform set up actions (if any) pass Def TearDown (self): # perfor M clean-up actions (if any) pass Def testsimplestring (self): R = Split (' GOOG 490.50 ') self.ass Ertequal (r,[' GOOG ', ' + ', ' 490.50 ']) def testtypeconvert (self): R = Split (' GOOG 490.50 ', [str, int., float]) Self.assertequal (r,[' GOOG ', 490.5]) def testdelimiter (self): R = Split (' goog,100,490.50 ', delimiter= ', ' ) self.assertequal (r,[' GOOG ', ' + ', ' 490.50 ']) # Run the Unittestsif __name__ = ' __main__ ': Unittest.main () #...#- ---------------------------------------------------------------------#Ran 3 teSTS in 0.001s#ok
When using unit tests, we need to define a inherit from UnitTest. The TestCase class. In this class, each test is defined in the form of a method and is named after the test--for example, 'testsimplestring', 'testtypeconvert' and a similar naming scheme (it is important to emphasize that, as long as the method name starts with test , it is possible to name it anyway). In each test, assertions can be used to check for different conditions.
Practical Examples:
If you have a method in the program, the output of this method points to standard output (sys.stdout). This usually means that you are outputting text messages to the screen. If you want to test your code to prove it, just give the corresponding input, then the corresponding output will be displayed.
# Url.pydef Urlprint (protocol, host, domain): url = ' {}://{}.{} '. Format (protocol, host, domain) print (URL)
The built-in print function sends output to Sys.stdout by default. To test that the output has actually arrived, you can simulate it with a surrogate object and assert the expected value of the program. The patch () method in the unittest.mock module can replace the object only in the context of running the test, returning the original state of the object immediately after the test is complete. Here is the test code for the Urlprint () method:
#urltest. Pyfrom IO import stringiofrom unittest import Testcasefrom Unittest.mock Import patchimport urlclass testurlprint (TestCase): def test_url_gets_to_stdout (self): protocol = ' http ' host = ' www ' domain = ' example.com ' Expected_url = ' {}://{}.{} \ n '. Format (protocol, host, domain) with patch (' Sys.stdout ', New=stringio ()) as Fake_out:url.urlprint (pr Otocol, host, domain) self.assertequal (fake_out.getvalue (), Expected_url)
The
Urlprint () function has three parameters, and the test code first assigns a dummy value to each parameter. The variable expected_url contains the expected output string. To be able to perform the test, we used the unittest.mock.patch () method as the context manager, putting the standard output sys.stdout is replaced with the Stringio object so that the content of the sent standard output is received by the Stringio object. The variable fake_out is the simulated object created in this procedure, which can be used in a block of code with which to perform a series of test checks. When the with statement is complete, the patch method can restore everything to the state it was in before the test was executed, as if the test had not been executed, without any additional work. But for some Python C extensions, this example is meaningless because these C extensions bypass the Sys.stdout setting and send the output directly to the standard output. This example applies only to pure Python code programs (if you want to capture input output like the C extension, you can do this by opening a temporary file and then redirecting the standard output to the file).