Summary:
This article describes how to use Jenkins and TestNG to implement a "self-service" automated test platform that meets the needs of complex testing. Based on Jenkins as a platform, the program combines powerful plug-ins and system configurations, deploys automated test packages based on TestNG, and provides a friendly Web access interface. Project members can access the platform from a browser at any time and place, and can select test environments, test sets, test cases, and submit automated test requests to achieve true "self-service" automated testing according to different requirements. This platform can greatly improve the efficiency and convenience of the development and test team automation scripts.
Catalogue: Design coding test of requirement scheme
Body:
I. Demand-making
Testing department to develop a set of its own quality center, mainly for the defect statistics, interface automation testing, app automation testing, online monitoring, in the interface Automation testing and application Automation testing process, we need to implement, users choose different test sets, the collection contains which test cases, TestNG will perform different test cases on its own, making different responses based on different input from the user.
Two. The Programme Design Quality Center (web) provides test case management and test collection management, creating test tasks, associating test sets, testing collections, and correlating test Case Quality Centers (web) to create test tasks corresponding to invoking the Jenkins task, and passing the corresponding parameters to pass through The Jenkins task starts by finding the appropriate test set and test case based on the incoming test task number, and using a Python script to generate the corresponding testng XML file, where the XML file defines the test cases that need to be executed, Make different corresponding Jenkins execute Python-generated testng XML document based on different input from the user TestNG after executing on Jenkins, the emailable-report.html test report is generated under the Surefine-reports folder. After the Jenkins task executes again, the Python script is called. Writes the generated emailable-report.html report to MySQL and stores it for Quality Center (WEB) viewing
Three. Encoding
3.1 Quality Center->app automated Test Database design
App_elements: Store App page controls, such as Android resource Id,ios XPath
App_execute: Storage supports execution results, test reports, test results, etc.
App_mobile: Information about the storage test model
App_modules: Storage test app contains modules, layered ideas, easy to manage
App_platform: Store test app to support multiple apps
App_suitecase: Storing the relationship between test sets and test cases, one test case corresponding to multiple test sets
App_testcase: Storing test Cases
App_testjob: Store test tasks, correlate the corresponding Jenkins paths, and execute them more directly
App_testsuite: Storage Test Collection
3.2 Jenkins parameter configuration
Testplatform: Test platform, Android or iOS
Testdevice: Test device, Android requires incoming Udid,ios not required
TESTENV: Test environment, QA or live
Testjobid: Test task number, this task number allows MySQL to query the associated test set and test cases in the collection
Testexecuteid: Perform the task number, pass in the Python script, tell the generated test report emailable-report.html to hold the corresponding location
3.3 Python file generation testng XML
#-*-coding:utf-8-*-import OS import mysqldb import sys import XML.DOM.MINIDOM # External incoming test task number test_job_id = Sys.argv[1]
# Connect DB def connect_db (db): db = MySQLdb.connect (host= "10.9.8.20", port=3306, User= "* * *", passwd= "* * *", DB=DB, CH arset= "UTF8") return DB # request MySQL to get Data def get_data (db, SQL): conn = connect_db (db) cur = conn.cursor () c Ur.execute (SQL) data = Cur.fetchall () cur.close () Conn.commit () Conn.close () return data # To determine if a file exists, If no immediate creation exists, delete immediately if present, re-overwrite def xml_exist (): file_name = Os.path.dirname (Os.path.dirname (Os.path.abspath (__file__))) +
"/resources/youyu_stock.xml" if Os.path.exists (file_name): Os.remove (file_name) f = open (file_name, "w") F.close () return file_name # get test Case English name Def get_case_name (): suite_id = Get_data ("App", "Select suite_id from App_testjob where id= "+TEST_JOB_ID) [0][0] case_id = Get_data ("App", "select case_id from App_suitecase where suite_id=" + str (suite_id)) List_case_name = [] for i in xrange (0, Len (case_id)): Case_name = Get_data ("Apps", "Select Ename from APP_TESTC ASE where id= "+ str (case_id[i][0])) [0][0] List_case_name.append (case_name) return list_case_name def main () : file_name = xml_exist () Case_names = Get_case_name () doc = xml.dom.minidom.Document () root = Doc.createe Lement ("Suite") Root.setattribute ("name", "TestSuite") Root.setattribute ("parallel", "false") Doc.appendchild ( Root) # Add parameter NodeManager = doc.createelement ("parameter") Nodemanager.setattribute ("name", "url") n Odemanager.setattribute ("Value", "127.0.0.1") Root.appendchild (nodemanager) NodeManager = doc.createelement ("param Eter ") Nodemanager.setattribute (" name "," Port ") Nodemanager.setattribute (" Value "," 4727 ") Root.appendchild (nod Emanager) Nodemanager = doc.createelement ("parameter") Nodemanager.setattribute ("name", "Device") Nodemanager.setattribute ("Value", "$ {testplatform} ") Root.appendchild (nodemanager) NodeManager = doc.createelement (" parameter ") Nodemanager.setatt Ribute ("name", "Udid") Nodemanager.setattribute ("Value", "${testdevice}") Root.appendchild (NodeManager) Nodema Nager = doc.createelement ("parameter") Nodemanager.setattribute ("name", "env") Nodemanager.setattribute ("Value", " ${TESTENV} ") Root.appendchild (NodeManager) # Add test case for I in xrange (0, Len (case_names)): Print CA Se_names[i] Node_test = doc.createelement ("Test") Node_test.setattribute ("name", Case_names[i]) No de_classes = Doc.createelement ("Classes") Node_test.appendchild (node_classes) Node_class = Doc.createeleme NT ("Class") Node_class.setattribute ("Name", "
Com.youyu.stock.automation.mobile.testcase.registerAndLogin.RegisterAndLoginTestCase ") Node_classes.appendchild (node_class) node_methods = Doc.createelement ("Methods") Node_class.appendchild (
Node_methods) Node_include = Doc.createelement ("include") Node_include.setattribute ("name", Case_names[i]) Node_methods.appendchild (node_include) root.appendchild (node_test) f = file (file_name, "w") DOC.W
Ritexml (f, "\ T", "\ T", "\ n", "Utf-8") f.close () if __name__ = = ' __main__ ': Main ()
3.4 Jenkins configuration and execution maven TestNG
Maven pom.xml Definition:
<build> <pluginManagement> <plugins> <plugin> <groupid&
Gt;org.apache.maven.plugins</groupid> <artifactId>maven-surefire-plugin</artifactId> <version>2.19.1</version> <configuration> <systempro
Pertyvariables> <testEnvironment>${TestDevice}</testEnvironment> <testEnvironment>${TestEnv}</testEnvironment> <testenvironment>${testjobid
}</testenvironment> </systemPropertyVariables> <suiteXmlFiles> <suiteXmlFile>${automationFile}</suiteXmlFile> </SUITEXMLFILES&G
T </configuration> </plugin> <plugin> <groupid>org.apache.ma Ven.pLugins</groupid> <artifactId>maven-compiler-plugin</artifactId> <conf
Iguration> <source>1.8</source> <target>1.8</target>
</configuration> </plugin> </plugins> </pluginManagement> </build>
3.5 The generated testng XML file, for example:
3.6 generated emailable-report.html stored in MySQL
#-*-coding:utf-8-*-import OS import sys import mysqldb from BS4 import BeautifulSoup # External incoming execute task when parameter number execute_id = Sy
S.ARGV[1] # Connect DB def connect_db (db): db = MySQLdb.connect (host= "10.9.8.20", port=3306,
User= "* * *", passwd= "* * *", db=db, charset= "UTF8") return DB # request MySQL to get Data def get_data (db, SQL): conn = connect_db (db) cur = Conn.curso R () cur.execute (sql) data = Cur.fetchall () cur.close () Conn.commit () Conn.close () return Data de F Write_result (): File_path = Os.path.dirname (Os.path.dirname (Os.path.abspath)) + "__file__ surefire-reports/emailable-report.html "f = open (File_path," r ") HTML = f.read () # test result written to MySQL soup = Beau Tifulsoup (HTML) passcase = Int (soup.find_all ("th", class_= "num") [0].get_text ()) failcase = Int (soup.find_all ("th", class_= "num") [2].get_text ()) # Test Report Writeinto MySQL HTML = mysqldb.escape_string (HTML) get_data ("app", "Update App_execute set test_result=\"%s\ ", test_report=
\ "%s\" where id=%s "% (str (passcase) +"/"+ str (passcase+failcase), HTML, str (EXECUTE_ID))) if __name__ = = ' __main__ ': Write_result ()
Four. Testing
4.1 Quality Platform
Summarize:
In order to practice according to the user different input to make different corresponding, the period tries the scheme as follows: TestNG @Test Enabled=false or True failed, reason for failure: Enabled incoming value must be fixed value TestNG Automatic-testname can execute different test cases according to the different testing name options passed in, failed, too many dependent packages, MAVEN project download package cannot be installed classpath way to local classpath,maven to do a layer of encapsulation, Maven dependences maven executes command line MVN clean test to pass testng parameters in, fail, reason for failure: Maven-dtest only chooses what needs to be done, and does not know the parameters in testng
Reference documents:
Integrated Jenkins and TestNG for self-service automated test platforms
Http://testng.org/doc/index.html