The framework can focus on and write test cases, the tedious coding work is all dry, can customize plug-ins, such as cracking verification codes, failed screenshots, etc. After the test case is written, you can automatically test, generate reports, and send mail by simply specifying the plug-ins and test cases used
from case.reader.excel import ExcelReader
from execute.driverexecute import NormalExecutor
from plugin.assertplugin import AssertPlugin
from report.Runner import Run
from report.report import Report
if __name__ == '__main__':
r = Run()
r.add_executor(NormalExecutor())
r.add_plugin(AssertPlugin("assertion"))
r.add_reader(ExcelReader())
r.generator_file("case")
report = Report()
report.start()- Reader: A tool for reading data, you can specify a file or database or customize
- Case: The positioning method of an element performs actions, etc. (one execution step)
- Process: A series of execution steps (sorted by id)
- Package: The basic unit of transportation is used to package a Process or multiple Processes
- Packages: Collection of all packages
- Packager: Responsible for combining Case and Process into Packages to form Packages
- Porter: Responsible for fetching data from Packager to CaseManager
- CaseManager: Responsible for managing multiple Porters and Packagers
- ExecuteCenter: Responsible for obtaining Packages from CaseManager's porters and distributing them to Manager
- Manager: Assign each package in packages to a registered Executor
- Executor: Responsible for unpacking the package to get Process and execute
- PluginCenter: Plugin Center, responsible for plugin registration management, etc.
- Plugin: Plugin, register the function to PluginCenter after the function is implemented, and call the function when testing
- Generator: used to generate Test scripts
- Report: Execute use case generation report
Read the test case (db, file) by Reader -> Form each execution step (Case) -> Multiple execution steps to form the process (Process)
Packager Packages Process -> Multiple Packages Form Packages (Packages, Scalable to Asynchronous Operations, Distributed Operations)
Shipment of Packages to CaseManager by Porter -> Scheduled by Manager to Command Execution Center (ExecutorCenter)
ExecutorCenter unpacks and distributes to the executor -> each executor performs the task assigned to itself
- PIL
- pytesseract
- matplotlib
- opencv
- selenium
PageObject will automatically generate xxx.ini files based on test cases, which will be cleaned each time it is executed.
1.All sections are elements required for a test flow
2.All elements are named:
elementName.method -> indicates how the element is positioned
elementName.value -> represents the value of the element's position
3.Elemental positioning
"id": id targeting
"xpath": xpath targeting
"link_text" link text
"partial_link_text": text containing link
"name": element name
"tag_name": element tag name
"class_name": class name
"css_selector": css selector
4.Element name naming
Name:
elementName_controlName
The meaning of the elements such as username, password, etc. are named using a camel
E.g:
Input box:
ElementName _input:
Username input box -> user_input
Password input box -> pwd_input
Keyword search input box -> kw_search_input
Checkbox:
ElementName _checkbox:
Automatic login checkbox -> autoLogin_checkbox
5.Elemental behavior
Each element gives a certain behavior
Button behavior can be click, can be drag
The input box can be a click, it can be an input
Complete naming:
Element name_control name.action = behavior
E.g:
Password input box
registerPassword_input.method=id
registerPassword_input.value=user_password
registerPassword_input.action=send_keys
registerPassword_input.input_value=123456
The configuration file is placed in managers/config.py
# Set the path to the cache file
url = {
"page_object_file_path": "./"
}
# Configure selenium
selenium = {
"browser": "firefox",# specifies the browser to use
"os": "linux", # specifies the operating system to be used, if not specified, the current system will be used.
"driver_path": "/home/amdins/桌面/geckodriver" # Browser driver address
}
# Configure the path to store test scripts
report = {
"file_url": "/home/amdins/桌面/text"
}
# Configure settings for storing test cases
case = {
"type": "excel", # set the read case type
"url": "/home/amdins/桌面/SeleniumAutoTest/case.xlsx", # If it is a database, the url is the database link address
}
# All plugin names need to be registered in the plugins
plugins = [
"assertion"
]Test cases only support excel for the time being, but you can increase the reading method yourself.
Use case description:
| id | description | Generated element name | Element category | Targeting | Positioning value | action | input value | Waiting mode | waiting time | Execution action | Using plugins | Assertion condition |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Login link jump | loginLink | button | link_text | login | click | notWaiting | 0 | null | null | assertion:B,screen:B | contains(title |
Fill in the plugin name, separated by commas, you need to specify when to execute B to execute before executing the test case, and A to execute after executing the test case.
Not using a plugin can be empty or null
Assertions are done using the assertion plugin, and the assertion mode is customizable
The element actions are as follows:
- Click (click on the element)
- Input (need to write the input value in the input value)
- Select (select the box, enter the value you need to write the content in the input value eg: (text, male), indicating that the option to use the text mode to select the value of male)
- js (js code to be executed needs to write the input content in the input value)
- iframe (switch iframe, the default value is change)
note: Assertion plugin is already registered by default, the name is assertion
Can specify when the plugin is executing
E.g: Execute before the test case: assertion: B (before) Execute after the test case: assertion: A (After)
from plugin.base import BasePlugin
from exception.assertion import Assertion
class ScreenPlugin(BasePlugin):
def start(self, driver,case):
"""
Driver for webdriver object
Case is the current execution case
"""
if case.assertion not in driver.page_source:
raise Assertion()Assertion plugin throws AssertionError() when assertion fails
- contains
- exist (to be completed)
- is (consistent)
- true (whether the result is True)
- false (whether the result is False)
- enable (the element is available)
- display (the element is visible)
- selected (whether the element is selected)
- notnull (not empty)
Is (content :: 'assertion value')
Element keyword
- title: assert the browser title value
- element: get the element
- element_is: determine the element type
- element_attr: get the element value
- element_property: get the element attribute
- element_text: get the element text information
- js: execute javascript command
Title
Use back quotation marks '`'
element_attr|`location method`, `location value`, `property name`|
E.g:
element_attr|`id`,`username`,`data`|
Use back quotation marks '`'
element_property|`location method`, `location value`, `property name`|
E.g:
element_property|`id`,`username`,`data`|
js|alter('hello')|
<a class="big">hello</a>is(element_text|`class`,`.big`|::'hello')
<a class="big" data="1">hello</a>is(element_attr|`class`,`.big`,`data`|::'1')
<div id="best-content" accuse="aContent" class="best-text mb-10">
<div class="wgt-best-mask">
<div class="wgt-best-showbtn">
show all<span class="wgt-best-arrowdown"></span>
</div>
</div>
hello world
</div>
is(js|`return document.getElementById("best-content").innerText;`|::'hello world')
Implementation principle: Generate xx_test.py file according to test case, then use unittest's testLoader, combined with TestRunner
cover = unittest.defaultTestLoader.discover("<path>", pattern="*_test.py")
with open("result.html", 'wb') as f:
HTMLTestRunner(title="name of test", description="case description",
tester="who test",
stream=f).run(cover)from case.reader.excel import ExcelReader
from execute.driverexecute import NormalExecutor
from plugin.assertplugin import AssertPlugin
from report.Runner import Run
# generator
r = Run()
# register executor
r.add_executor(NormalExecutor())
# register plugin
r.add_plugin(AssertPlugin("assertion"))
# register Reader
r.add_reader(ExcelReader())
# generate file
r.generator_file("case")import unittest
from managers.manager import Manager
from case.reader.excel import ExcelReader
from execute.driverexecute import NormalExecutor
from plugin.assertplugin import AssertPlugin
man = Manager()
man.select_reader(ExcelReader())
man.register_executor(NormalExecutor())
man.register_plugin(AssertPlugin('assertion'))
execute = man.get_execute()
class case(unittest.TestCase):
def test_Test(self):
execute.run_by_name('Test')- frame skeleton
- plugin support
- rich element action
- assertion plugin
- Test report generation (to be improved)
- Email support
- More plugin
- Asynchronous execution
- More browser behavior
- Read test cases from the database
- Remote test support
- as a Docker service