Package: pyqt-autotest
pyqt-autotest ⚙️🧪A command line tool for finding system-level bugs that cause a python Qt application to terminate. This is achieved by simulating user actions on a widget usingQtTest.This tool requires you to provide a python class which inherits from the providedRandomAutoTestclass. The widget defined inside this class will be opened a specified number of times, and a random selection of actions is performed on the children widgets within the encompassing widget. The result of each run is recorded, and warnings/errors are captured, before a report is generated to provide reliable instructions for how to reproduce a bug.Table of contentsInstallationSetupOptionsTest classBuilt-in ActionsCreating your own ActionsUsageOutputInstallationThis package can be installed fromPyPIusing pip.pipinstallpyqt-autotestSetupCreate a file named.autotestin your home directory with the following contents.[setup]
search_directories = /path/to/test/directory1/
                     /path/to/test/directory2/
output_directory = /path/to/output/directory/Thesearch_directoriesoption is used to specify the directories to search for python files containing your test classes. Theoutput_directoryoption is used to specify the directory to store the output results in.OptionsThe following table details the options that can be provided on the command line.OptionDescriptionDefaultCommand line optionTests regexRun tests matching this regular expression. The directories provided in the.autotestconfiguration file are searched for matching tests.-R, --tests-regexList testsFlag which lists the tests that are found in the search directories specified by the.autotestconfiguration file. The tests are not run.False-l, --list-testsNumber of runsThe number of times to open the widget and perform a random selection of actions.1-n, --number-of-runsNumber of actionsThe number of random actions to perform each time the widget is opened.10-a, --number-of-actionsWait timeThe number of milliseconds to wait between executing two consecutive actions.50-w, --wait-timeOutput nameThe name to give the output file. The output file is stored in the output_directory specified by the.autotestconfiguration file.No output file is generated.-o, --output-nameCautiousFlag which saves the output file before each action is performed. This ensures an output file is still created after a terminating fault.False-c, --cautiousVerboseFlag which prints more debug information when supplied. It also prints the actions just before each of them is performed.False-v, --verboseTest classThe first thing to do is to create a python class which inherits fromRandomAutoTest, and implement thesetup_widgetmethod. Inside this method, you should instantiate yourQWidgetand assign it to the member variableself.widgetas follows. Any additional setup, such as loading data into your widget, should also be done in the same method.fromusercode.modelimportExampleModelfromusercode.presenterimportExamplePresenterfromusercode.viewimportExampleViewfrompyqt_autotest.random_auto_testimportRandomAutoTestclassExampleTest(RandomAutoTest):defsetup_widget(self):# The 'self.widget' member variable MUST be instantiated, and it must be a QWidget.self.widget=ExampleView()# Other relevant setup should be done here too. This example refers to the Model-View-Presenter (MVP) patternself.model=ExampleModel()self.presenter=ExamplePresenter(self.widget,self.model)# Your test might be more interesting if you first load data into the widgetself.presenter.load_data("fake_data_file.dat")Optionally, you can also create asetup_optionsmethod to specify commonly used options. However, these options will be overridden if provided on the command line. Note that theOutput Nameoption cannot be provided in this setup method.defsetup_options(self):self.options.number_of_runs=2self.options.number_of_actions=15self.options.wait_time=200# millisecondsBuilt-in ActionsThe following actions are built-in to this package. Only these actions can be performed if you do not create your own (see the section below onhow to create your own).Built-in ActionDescriptionPython CallableAction.KeyDownClickSimulates the Down key being pressed on an active widget.lambda widget: QTest.keyClick(widget, Qt.Key_Down)Action.KeyUpClickSimulates the Up key being pressed on an active widget.lambda widget: QTest.keyClick(widget, Qt.Key_Up)Action.MouseLeftClickSimulates a widget being left clicked by the mouse.lambda widget: QTest.mouseClick(widget, Qt.LeftButton)These actions will by default be performed for the following widget types. This has been made minimalistic on purpose because this command line tool is arguably more useful if you carefully customize your own actions as seen in the next section.Widget typeBuilt-in ActionsQPushButtonAction.MouseLeftClickCreating your own ActionsThis package provides a great amount of flexibility for you to create and customize the actions you want to be available during a 'random auto test'. It also allows you to ignore certain widget types by not providing any actions for them.The following code provides a basic example for how to define your own custom actions:defsetup_options(self):# The 'actions' dictionary requires a string to describe an action, and a callable function which uses QtTest to# perform an action. Note that the 'Left click in centre' action is useful for testing a QCheckBox.actions={"Enter dummy text":lambdawidget:QTest.keyClicks(widget,"dummy text"),"Left click in centre":lambdawidget:QTest.mouseClick(widget,Qt.LeftButton,pos=QPoint(2,widget.height()/2))}# The 'widget_actions' dictionary requires you to specify which actions can be performed on which widget types.# Note that you can use the built-in actions, or create your own with a string name. The string name is used to# describe what an action does when generating the output instructions, so make sure it is short but descriptive.widget_actions={QCheckBox:["Left click in centre"],QLineEdit:["Enter dummy text"],QSpinBox:[Action.KeyDownClick,Action.KeyUpClick]}# This will overwrite the built-in actions. You could use 'dict::update' to keep the built-in actions.self.options.actions=actionsself.options.widget_actions=widget_actionsUsageIt is trivial to run your test class from the command line as follows (depending on its module location):autotest-RExampleTestor with more arguments:autotest -R ExampleTest -n 5 -a 10 -w 150 -o autotest_results -vOutputAn output json file will only be generated if anOutput Nameis provided from the command line using the-o, --output-nameoption. Alternatively, you can use theVerboseflag to get debug information from your terminal using the-v, --verboseoption.