Skip to main content

Behaviour Driven Development for python

Project description

环境要求

python3.7 及以上 pip install lettuce-Dtester

新增指令

--lf, --ff, --cc, --tn II --last-failed, --failed-first, --clear-cache, --task-name

--lf: 仅执行上次未通过的测试案例

--ff: 优先执行未通过的测试案例,通过的测试案例滞后执行

--cc: 清除case_cache

--tn: 在不与其他三个命令一起使用时指的是指定任务目录即 festures文件夹下的目录

--lf --tn task_name: 仅执行指定任务的未通过案例

--ff --tn task_name: 优先执行执行指定任务的未通过案例

--cc --tn task_name: 删除指定任务所有缓存文件,再次执行

--cc --lf --tn task_name: 会报错,因为会优先删除缓存文件,删除后无法支持--lf指令

--cc --ff --tn task_name: 会报错,因为会优先删除缓存文件,删除后无法支持--ff指令

目录信息

在根目录下生成case_cache目录
目录结构如下:(以本次执行案例文件夹为features/fee_test举例)
|---case_cache
    |---{task_name}_cache
        |---{task_name}(保存本次执行的py文件,用于后续的--ff, --lf执行)
            |---...py(指代保存的py文件)
        |---run_res(保存执行结果)
            |---error_case.feature(保存出错或跳过的案例原文)
            |---failed_first_case.feature(保存全部案例,但是出错的测试案例在前面)
            |---res.txt(保存错误或跳过的测试案例原始信息包含报错详情)
        |---lf_res(保存lf执行后结果,不执行lf命令不生成)
            |---error_case.feature
            |---failed_first_case.feature
            |---res.txt
        |---ff_res(保存ff执行后结果,不执行ff命令不生成)
            |---error_case.feature
            |---failed_first_case.feature
            |---res.txt

使用方法

在项目根目录下存在mian.py/run.py作为入口:

import lettuce
import os


class HtmlRunner(lettuce.Runner):
    def __init__(self, base_path, enable_html=False, html_filename=None, enable_email=False, recipients=None,
                 smtp_host=None, smtp_port=None, credential=None, *args, **kwargs):
        lettuce.Runner.__init__(self, base_path, *args, **kwargs)


def test_a():
    run_path = lettuce.run_task('case_a')
    base_path = os.path.join(os.path.dirname(os.curdir),
                             run_path)  # the path of .py and .feature
    lettuce.world.task_path = base_path
    tests_runner = HtmlRunner(base_path,
                              enable_html=True,
                              tags=("run",),
                              enable_xunit=True,
                              verbosity=4)
    tests_runner.run()


if __name__ == '__main__':
    test_a()

修改信息

新增文件:cacheprovider.py

修改lettuce:__init__.py 引用:

from lettuce.cacheprovider import  build_failed_first_case, run_task

修改lettuce/plugins/colored_shell_output.py 文件获取案例信息


def wp(l):
    if l.startswith("\033[1;32m"):
        l = l.replace(" |", "\033[1;37m |\033[1;32m")
    if l.startswith("\033[1;36m"):
        world.skip_flag = True
        l = l.replace(" |", "\033[1;37m |\033[1;36m")
    if l.startswith("\033[0;36m"):
        world.skip_flag = True
        l = l.replace(" |", "\033[1;37m |\033[0;36m")
    if l.startswith("\033[0;31m"):
        world.fail_flag = True
        l = l.replace(" |", "\033[1;37m |\033[0;31m")
    if l.startswith("\033[1;30m"):
        l = l.replace(" |", "\033[1;37m |\033[1;30m")
    if l.startswith("\033[1;31m"):
        world.fail_flag = True
        l = l.replace(" |", "\033[1;37m |\033[0;31m")   
    return l


def wrt(what):
    if six.PY2:
        if isinstance(what, unicode):
            what = what.encode('utf-8')
    if six.PY3:
        if isinstance(what, bytes):
            print(what)
            what = what.decode('utf-8')
    world.case.append(what)
    sys.stdout.write(what)

修改registry.py生成缓存
增加build_case方法
def case_data():
    temp_list = list()
    _case = world.case[:]
    for i in _case:
        a = i.replace("\033[1;37m", '')
        a = a.replace("\033[1;32m", '')
        a = a.replace("\033[1;30m", '')
        a = a.replace("\033[0m", '')
        a = a.replace("\033[A", '')
        a = a.replace("\033[0;36m", '')
        if not a.startswith("Feature"):
            if a in temp_list:
                ...
            else:
                temp_list.append(a)
                yield a

def build_case(scenario):

    if world.fail_flag is True or world.skip_flag is True:
        with open(f'{world.cache_path}/res.txt', 'a+', encoding='utf8') as f:
            with open(f'{world.cache_path}/error_case.feature', 'a+', encoding='utf8') as c:
                for a in case_data():
                    # 收集错误案例详情,支持-lf指令执行上次失败的案例
                    if "\033[0;31m" not in a and "\033[1;31m" not in a:
                        if "#" in a:
                            c.write(a.split('#')[0].rstrip() + '\n')
                        elif "|" in a:
                            c.write(a)
                    # 收集错误信息,保存在结果文件
                    a = a.replace("\033[0;31m", 'error!')
                    a = a.replace("\033[1;31m", 'error!')
                    a = a.replace("\033[1;41;33m", '')
                    f.write(f'{a}\n')                        
    else:
        with open(f'{world.cache_path}/temp_case.feature', 'a+', encoding='utf8') as t:
            for a in case_data():
                if "#" in a:
                    t.write(a.split('#')[0].rstrip() + '\n')
                elif "|" in a:
                    t.write(a)
    if world.fail_flag is True or world.skip_flag is True:
        world.case_log_name = int(time.time())
        with open(f'{world.cache_path}/res.txt', 'a+', encoding='utf8') as f:
            f.write(f'日志详情见:{world.case_log_name}')

    world.fail_flag = False
    world.skip_flag = False
    world.case = []
修改CallbackDict类,在每次执行一条案例完成后增加构建缓存函数
class CallbackDict(dict):
    def append_to(self, where, when, function):
        if not any(_function_matches(o, function) for o in self[where][when]):
            self[where][when].append(function)
            if where == 'scenario' and when == 'after_each':
                self[where][when].append(build_case)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lettuce_Dtester-0.2.31.tar.gz (56.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lettuce_Dtester-0.2.31-py3-none-any.whl (76.3 kB view details)

Uploaded Python 3

File details

Details for the file lettuce_Dtester-0.2.31.tar.gz.

File metadata

  • Download URL: lettuce_Dtester-0.2.31.tar.gz
  • Upload date:
  • Size: 56.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.7

File hashes

Hashes for lettuce_Dtester-0.2.31.tar.gz
Algorithm Hash digest
SHA256 80a9f018734b9057c64e98b7e9f35ad678482813d1e453fe5a7cd4737433f223
MD5 58e58acdd6c6e2aa98a52b1e901efc8d
BLAKE2b-256 0fbb38325f5b1312474d2bf38017dbf04bd2216c1a444b095fb50abcf392ae72

See more details on using hashes here.

File details

Details for the file lettuce_Dtester-0.2.31-py3-none-any.whl.

File metadata

File hashes

Hashes for lettuce_Dtester-0.2.31-py3-none-any.whl
Algorithm Hash digest
SHA256 76eb66fd60e2bb4aaf59333432c5e6d555133360b20b352ee7cca02487599a9a
MD5 fa5c7c5ebf761b6c10b2ae673bd3eef4
BLAKE2b-256 d201a9a9b958f858955915195419c4ae8576385be360454ac632bee63d542c9e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page