As explain in the Design document, a TestSuite in the Mago framework contains two different files, a .py file with the TestSuite class and methods and a .xml file, with the description of the TestSuite.
When writing a new TestSuite with the Mago framework, based on already available applications in the library, create the .py file and the .xml based on the following templates (available classes):
Python File
1 import ldtp
2 import ldtputils
3
4 # import the TestSuite class
5 from mago.testsuite.main import TestSuite
6 # import the necessary GNOME applications
7 from mago.application.gnome import <BaseClass>
8
9 class <SuiteClass>(TestSuite):
10
11 def setup(self):
12 #setup code, put here what happens at
13 #the beginning of the testsuite
14
15 def teardown(self):
16 #teardown code, put here what happens when
17 #the testsuite finishes
18
19 def cleanup(self):
20 # Add here what happens between test cases,
21 # i.e. cleaning logs and/or temp files
22
23 def <method1>(self, arg1, arg2):
24
25 self.do_stuff()
26 self.do_stuff()
27
28 if do_some_check() == FAIL:
29 raise AssertionError, "Human readable message"
30
31 if __name__ == "__main__":
32 <example_test> = <SuiteClass>()
33 <example_test>.run()
The python file contains the code for the test script. We are going through the script lines, explaining each of them.
- 1,2: Needed only when calling ldtp functions directly in the script.
5: TestSuite is the base class for a new test suite
11: SuiteClass is the name of the class for the giving suite. Anyname would do, but a descriptive name is better.
11: In general, test suites will inherit from TestSuite class
- 13: The setup method will be called at the beggining of a test suite, but not between test cases within the same suite.
- 17: The teardown method will be called at the end of a complete test suite, but not between test cases within the same suite.
- 21: The cleanup method will be called at the end of each test case. Write code that cleans up the mess introduced by a test case that could interfere with the next one.
- 25: method1. A suite can contain as many methods as needed. This is were the script code is written.
27,28: call any methods in the BaseClass to perform the script actions
30: Do some check after the script to assert that it passed. Raise an AssertionError if something failed.
- You can also return a list on success (message, screenshot), that will log a message and will grab a screenshot. message will be a string, screenshot, the path of screenshot file.
33: The main class just creates an instance of the SuiteClass and calls the run method. The TestSuite runner will do the rest.
Single Application Test Suite
One common use case is having a test suite that only test one application. For those cases the setup, teardown and cleanup methods normally contain common code (i.e. setup, opens the application, teardown closes the application, etc.).
For those cases, the test suite can be inherited from one of the SingleApplication test suites, that already implement those methods.
For example, to create a test suite that only test Gedit, the python template above can be changed for:
1 import ldtp
2 import ldtputils
3
4 # Instead of importing the Base application, import the base test suite
5 from mago.test_suite.gnome import GEditTestSuite
6
7 class <SuiteClass>(GEditTestSuite):
8
9 def <method1>(self, arg1, arg2):
10
11 self.do_stuff()
12 self.do_stuff()
13
14 if do_some_check() == FAIL:
15 raise AssertionError, "Human readable message"
16
17 if __name__ == "__main__":
18 <example_test> = <SuiteClass>()
19 <example_test>.run()
In this case, the setup, teardown and cleanup methods are implemented in the GEditTestSuite class.
XML File
<?xml version="1.0"?> <suite name="A name for your suite"> <class>{module_name}.{SuiteClass}</class> <description> A nice description about the purporse of the test suite </description> <!-- args of the suite main class --> <args> <arg1>contentofarg1</arg1> <arg2>contentofarg2</arg2> ... <argN>contentofargN</argN> </args> <case name="{NameCase1}"> <method>{methodcase1}</method> <description>A description of the first testcase</description> <!-- args of the case method --> <args> <arg1>contentofarg1</arg1> <arg2>contentofarg2</arg2> ... <argN>contentofargN</argN> </args> </case> <case name="{NameCase2}"> <method>{methodcase2(couldbethesameas1)}</method> <description>A description of the second testcase</description> <args> <arg1>contentofarg1</arg1> <arg2>contentofarg2</arg2> ... <argN>contentofargN</argN> </args> </case> </suite>
The XML file is almost self-describing. The most important parts of it are explained below:
- The suite root node has a name attribute, with the name of the suite.
The <class> tag contains the module name of the .py file and the SuiteClass class (same as the one in the .py file)
The <description> tag contains a human readable description of the purpose of the suite.
- The test suites can have 0 or more arguments (they will be passed to the constructor)
- For each case in the suite we will add a case child node with the following content:
- A name attribute with the name of the case
The <method> tag contains the name of the method of the SuiteClass to run for that particular test case.
The <description> tag describes the test case in a human readable manner.
Add a new child tag to the <args> tag with the argument name of the test case method.
- i.e. if the method signature is something like:
def my_method(self, name, surname):
then, the <args> node of the XML file will contain something like:
<args> <name>John</name> <surname>Smith</surname> </args>
That allow us to use the same method for different test cases.
- i.e. if the method signature is something like: