new feature: ate-locust

This commit is contained in:
debugtalk 2017-08-18 17:23:47 +08:00
parent a871bcf837
commit 148b2b9e9c
10 changed files with 154 additions and 11 deletions

3
.gitignore vendored
View File

@ -7,4 +7,5 @@ dist/*
*.egg-info *.egg-info
.python-version .python-version
logs/% logs/%
.coverage .coverage
locustfile.py

View File

@ -38,8 +38,8 @@ To ensure the installation or upgrade is successful, you can execute command `at
```text ```text
$ ate -V $ ate -V
jenkins-mail-py version: 0.2.4 jenkins-mail-py version: 0.2.5
ApiTestEngine version: 0.3.3 ApiTestEngine version: 0.4.0
``` ```
Execute the command `ate -h` to view command help. Execute the command `ate -h` to view command help.
@ -213,10 +213,45 @@ $ ate filepath/testcase.yml --report-name ${BUILD_NUMBER} \
--jenkins-build-number ${BUILD_NUMBER} --jenkins-build-number ${BUILD_NUMBER}
``` ```
## Performance test
With reuse of [`Locust`][Locust], you can run performance test without extra work.
```bash
$ ate-locust -V
Locust 0.8a2
```
For full usage, you can run `ate-locust -h` to see help, and you will find that it is the same with `locust -h`.
The only difference is the `-f` argument. If you specify `-f` with a Python locustfile, it will be the same as `locust`, while if you specify `-f` with a `YAML/JSON` testcase file, it will convert to Python locustfile first and then pass to `locust`.
```bash
$ ate-locust -f examples/first-testcase.yml
[2017-08-18 17:20:43,915] Leos-MacBook-Air.local/INFO/locust.main: Starting web monitor at *:8089
[2017-08-18 17:20:43,918] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2
```
In this case, you can reuse all features of [`Locust`][Locust].
Enjoy!
## Supported Python Versions ## Supported Python Versions
Python `2.7`, `3.3`, `3.4`, `3.5`, `3.6` and `3.7-dev`. Python `2.7`, `3.3`, `3.4`, `3.5`, `3.6` and `3.7-dev`.
`ApiTestEngine` has been tested on `macOS`, `Linux` and `Windows` platforms.
## Development
To develop or debug `ApiTestEngine`, you can install relevant requirements and use `main-ate.py` or `main-locust.py` as entrances.
```bash
$ pip install -r requirements_dev.txt
$ python main-ate -h
$ python main-locust -h
```
## To learn more ... ## To learn more ...
- [《接口自动化测试的最佳工程实践ApiTestEngine](http://debugtalk.com/post/ApiTestEngine-api-test-best-practice/) - [《接口自动化测试的最佳工程实践ApiTestEngine](http://debugtalk.com/post/ApiTestEngine-api-test-best-practice/)

View File

@ -1 +1 @@
__version__ = '0.3.4' __version__ = '0.4.0'

View File

@ -1,15 +1,17 @@
import argparse import argparse
import codecs
import logging import logging
import os import os
import sys
from collections import OrderedDict from collections import OrderedDict
import PyUnitReport import PyUnitReport
from ate import __version__ from ate import __version__
from ate.task import create_task from ate.task import create_task
def main(): def main_ate():
""" parse command line options and run commands. """ API test: parse command line options and run commands.
""" """
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='Api Test Engine.') description='Api Test Engine.')
@ -81,3 +83,65 @@ def main():
mailer.send_mail(subject, results, flag_code) mailer.send_mail(subject, results, flag_code)
return flag_code return flag_code
def main_locust():
""" Performance test with locust: parse command line options and run commands.
"""
try:
from locust.main import main
except ImportError:
print("Locust is not installed, exit.")
exit(1)
sys.argv[0] = 'locust'
if len(sys.argv) == 1:
sys.argv.extend(["-h"])
if sys.argv[1] in ["-h", "--help", "-V", "--version"]:
main()
sys.exit(0)
try:
testcase_index = sys.argv.index('-f') + 1
assert testcase_index < len(sys.argv)
except (ValueError, AssertionError):
print("Testcase file is not specified, exit.")
sys.exit(1)
testcase_file_path = sys.argv[testcase_index]
sys.argv[testcase_index] = parse_locustfile(testcase_file_path)
main()
def parse_locustfile(file_path):
""" parse testcase file and return locustfile path.
if file_path is a Python file, assume it is a locustfile
if file_path is a YAML/JSON file, convert it to locustfile
"""
if not os.path.isfile(file_path):
print("file path invalid, exit.")
sys.exit(1)
file_suffix = os.path.splitext(file_path)[1]
if file_suffix == ".py":
locustfile_path = file_path
elif file_suffix in ['.yaml', '.yml', '.json']:
locustfile_path = gen_locustfile(file_path)
else:
# '' or other suffix
print("file type should be YAML/JSON/Python, exit.")
sys.exit(1)
return locustfile_path
def gen_locustfile(testcase_file_path):
""" generate locustfile from template.
"""
locustfile_path = 'locustfile.py'
with codecs.open('ate/locustfile_template', encoding='utf-8') as template:
with codecs.open(locustfile_path, 'w', encoding='utf-8') as locustfile:
template_content = template.read()
template_content = template_content.replace("$HOST", "https://skypixel.com")
template_content = template_content.replace("$TESTCASE_FILE", testcase_file_path)
locustfile.write(template_content)
return locustfile_path

26
ate/locustfile_template Normal file
View File

@ -0,0 +1,26 @@
#coding: utf-8
import zmq
import os
from locust import HttpLocust, TaskSet, task
from ate import utils, runner, exception
class WebPageTasks(TaskSet):
def on_start(self):
self.test_runner = runner.Runner(self.client)
self.testset = self.locust.testset
@task
def test_specified_scenario(self):
try:
self.test_runner.run_testset(self.testset)
except exception.ValidationError:
pass
class WebPageUser(HttpLocust):
host = "$HOST"
task_set = WebPageTasks
min_wait = 1000
max_wait = 5000
testsets = utils.load_testcases_by_path("$TESTCASE_FILE")
testset = testsets[0]

5
main-ate.py Normal file
View File

@ -0,0 +1,5 @@
""" used for debugging
"""
from ate.cli import main_ate
main_ate()

5
main-locust.py Normal file
View File

@ -0,0 +1,5 @@
""" used for debugging
"""
from ate.cli import main_locust
main_locust()

View File

@ -1,2 +0,0 @@
from ate.cli import main
main()

View File

@ -5,3 +5,4 @@ coveralls
coverage coverage
-e git+https://github.com/debugtalk/PyUnitReport.git#egg=PyUnitReport -e git+https://github.com/debugtalk/PyUnitReport.git#egg=PyUnitReport
-e git+https://github.com/debugtalk/jenkins-mail-py.git#egg=jenkins-mail-py -e git+https://github.com/debugtalk/jenkins-mail-py.git#egg=jenkins-mail-py
-e git+https://github.com/locustio/locust.git#egg=locustio

View File

@ -17,6 +17,9 @@ setup(
url='https://github.com/debugtalk/ApiTestEngine', url='https://github.com/debugtalk/ApiTestEngine',
license='MIT', license='MIT',
packages=find_packages(exclude=['test.*', 'test']), packages=find_packages(exclude=['test.*', 'test']),
package_data={
'ate': ['locustfile_template'],
},
keywords='api test', keywords='api test',
install_requires=[ install_requires=[
"requests", "requests",
@ -29,11 +32,15 @@ setup(
extras_require={ extras_require={
'mail': [ 'mail': [
"jenkins-mail-py" "jenkins-mail-py"
],
'locust': [
"locustio"
] ]
}, },
dependency_links=[ dependency_links=[
"git+https://github.com/debugtalk/PyUnitReport.git#egg=PyUnitReport-0", "git+https://github.com/debugtalk/PyUnitReport.git#egg=PyUnitReport-0",
"git+https://github.com/debugtalk/jenkins-mail-py.git#egg=jenkins-mail-py-0" "git+https://github.com/debugtalk/jenkins-mail-py.git#egg=jenkins-mail-py-0",
"git+https://github.com/locustio/locust.git#egg=locust-0"
], ],
classifiers=[ classifiers=[
"Development Status :: 3 - Alpha", "Development Status :: 3 - Alpha",
@ -46,7 +53,8 @@ setup(
], ],
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
'ate=ate.cli:main' 'ate=ate.cli:main_ate',
'ate-locust=ate.cli:main_locust'
] ]
} }
) )