前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何在python下建立cucumber项目

如何在python下建立cucumber项目

作者头像
顾翔
发布于 2024-09-10 05:35:45
发布于 2024-09-10 05:35:45
13400
代码可运行
举报
运行总次数:0
代码可运行

一、 Gherkin简介

Gherkin语言使用的是主要英文关键词Scenario、Given、when 、And、Then和But等,这些关键词可以转换成中文关键词,场景、假如、当、那么等。根据用户故事,需求人员或测试人员使用Gherkin语言编写好测试场景的每个步骤

feature文件的编写,遵循Gherkin语言规范:

  • Feature(特性):功能名称;
  • Description(描述)(可选):描述测试中的功能。
  • Scenario(场景):测试场景名称;
  • Given(假如):给出测试前提条件;
  • when(当):相当我们的测试步骤;
  • Then(那么):给出期望结果。

二、 目录

主目录

二级目录

描述

steps/

login.py

Step definitions for features.

reports/

jsonDumps/

Save behave json reports

jsonReports/

Save behave to cucumber json reports

environment.py

Environment for global setup…

login.feature

Feature files.

三、environment.py

每一个步骤之前,之后执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
before_step(context, step)
after_step(context, step)

在这里面的脚本会在每一个场景之前,之后执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
before_scenario(context, scenario)
after_scenario(context, scenario)

在这里面的脚本会在每一个feature之前,之后执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
before_feature(context, feature)
after_feature(context, feature)

在脚本里面可以设置tag(这个之后会介绍),这里面的脚本会在含有tag的模块里面之前,之后执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
before_tag(context, tag)
after_feature(context, tag)

这里面的脚本会在整个脚本开始之前,之后执行 ——- 一般会在这里面添加一些setup的脚本,例如启动浏览器,设置一些变量,连接数据库,关闭浏览器,关闭数据库 等等

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
before_all(context)
after_all(context)

四 脚本

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip3 install behave

英文

4.1 在项目主目录中建立文件test.feature

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Feature: Login
  I want to test the login functionality
  Scenario: Successful Login
    Given I am on the login page
    When I enter valid credentials
    Then the homepage is displayed    
  Scenario: Failed Login
    Given I am on the login page   
    When I enter invalid credentials
    Then an error message is displayed

4.2 建立environment.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from selenium import webdriver
def before_all(context):
    context.browser = webdriver.Firefox()
def after_all(context):
    context.browser.quit()

4.3 建立steps目录

4.4 进入steps目录,建立login.py文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from behave import *
from selenium.webdriver.common.by import By
@given(u'I am on the login page')
def step_impl(context):
    context.browser.get("http://127.0.0.1:8000")
@when(u'I enter valid credentials')
def step_impl(context):
    context.browser.find_element(By.ID,"id_username").send_keys("cindy")
    context.browser.find_element(By.ID,"id_password").send_keys("123456")    
    context.browser.find_element(By.CSS_SELECTOR,"body > div > form > button").click()
@then(u'the homepage is displayed')
def step_impl(context):
    assert context.browser.find_element(By.NAME,"good").is_displayed()
@when(u'I enter invalid credentials')
def step_impl(context):
    context.browser.find_element(By.ID,"id_username").send_keys("cindy")
    context.browser.find_element(By.ID,"id_password").send_keys("654321")
    context.browser.find_element(By.CSS_SELECTOR,"body > div > form > button").click()
@then(u'an error message is displayed')
def step_impl(context):
assert context.browser.title != "电子商务系统"

4.5 打开被测系统,在命令行中运行behave

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PS C:\Users\xiang\Desktop\BDD> behave
Feature: Login # test.feature:1
  I want to test the login functionality
  Scenario: Successful Login       # test.feature:3
    Given I am on the login page   # steps/login.py:4
    When I enter valid credentials # steps/login.py:8
    Then the homepage is displayed # steps/login.py:14
           
  Scenario: Failed Login               # test.feature:7
    Given I am on the login page       # steps/login.py:4
    When I enter invalid credentials   # steps/login.py:18
    Then an error message is displayed # steps/login.py:24
           
1 feature passed, 0 failed, 0 skipped
2 scenarios passed, 0 failed, 0 skipped
6 steps passed, 0 failed, 0 skipped, 0 undefined    
Took 0m1.576s
PS C:\Users\xiang\Desktop\BDD>

中文

1 test.feature

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# language: zh-CN
功能:
 我想测试登录功能
场景:成功登录
 假如我在登录页面上
 当我输入有效凭据时
 那么显示主页
场景:登录失败
 假如我在登录页面上
 当我输入无效凭据时
 那么显示一条错误消息

2 login.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from behave import *
from selenium.webdriver.common.by import By
           
@given(u'我在登录页面上')
def step_impl(context):
    context.browser.get("http://127.0.0.1:8000")    
           
@when(u'我输入有效凭据时')
def step_impl(context):
    context.browser.find_element(By.ID,"id_username").send_keys("cindy")
    context.browser.find_element(By.ID,"id_password").send_keys("123456")
    context.browser.find_element(By.CSS_SELECTOR,"body > div > form > button").click()
           
@then(u'显示主页')
def step_impl(context):
    assert context.browser.find_element(By.NAME,"good").is_displayed()
           
@when(u'我输入无效凭据时')
def step_impl(context):
    context.browser.find_element(By.ID,"id_username").send_keys("cindy")
    context.browser.find_element(By.ID,"id_password").send_keys("654321")
    context.browser.find_element(By.CSS_SELECTOR,"body > div > form > button").click()
           
@then(u'显示一条错误消息')    
def step_impl(context):
    assert context.browser.title != "电子商务系统"

3 运行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PS C:\Users\xiang\Desktop\BDD(中文)>behave --lang zh-CN

五 数据驱动

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 test.feature
# language: zh-CN
功能:
 我想测试登录功能
场景大纲:登录
 假如我在登录页面上
 当我输入<用户名><密码>
 那么进入页面是<标题>
例子:
|用户名|密码|标题|
|cindy|123456|电子商务系统|
|cindy|654321|电子商务系统-登录|

2 login.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from behave import *
from selenium.webdriver.common.by import By
           
@given(u'我在登录页面上')    
def step_impl(context):
    context.browser.get("http://127.0.0.1:8000")
           
@when(u'我输入{username}和{password}')
def step_impl(context,username,password):
    context.browser.find_element(By.ID,"id_username").send_keys(username)
    context.browser.find_element(By.ID,"id_password").send_keys(password)
    context.browser.find_element(By.CSS_SELECTOR,"body > div > form > button").click()
           
@then(u'进入页面是{title}')
def step_impl(context,title):
    assert context.browser.title == title

六 报告

6.1 普通报告

  • pretty:这是默认的报告格式,提供颜色化的文本输出,每个测试步骤的结果都会详细列出。
  • plain:这也是一种文本格式的报告,但没有颜色,并且在执行每个步骤后只输出一个新行。
  • progress:这种报告格式只在执行每个测试步骤后输出一个单字符。
  • json:这种报告格式以 JSON 格式输出测试结果,易于进行进一步处理。使用 -f 参数或 --format 参数来指定报告的格式。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>behave --lang zh-CN -f json.pretty -o './reports/testResult.json'

6.2 allure报告

1 安装allure

2 运行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip3 install allure-behave

3 运行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
behave -f allure_behave.formatter:AllureFormatter -o allure_data

产生allure_data目录,里面包括json文件

4 运行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 allure serve allure_data
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
全面理解ThreadLocal(详细简单)
从Java官方文档中的描述:ThreadLocal类用来提供线程内部的局部变量。 这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程的变量。ThreadLocal的实例通常来说都是private static 类型的,用于关联线程和线程上下文。
终有救赎
2023/10/22
5770
全面理解ThreadLocal(详细简单)
ThreadLocal 的原理及问题,一网打尽!
ThreadLocal 是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对于其他线程来说无法获取到数据。
田维常
2023/11/30
2610
ThreadLocal 的原理及问题,一网打尽!
ThreadLocal的应用场景和注意事项有哪些?
最近一个小伙伴把项目中封装的日期工具类用在多线程环境下居然出了问题,来看看怎么回事吧
Java识堂
2020/04/22
1K0
ThreadLocal的应用场景和注意事项有哪些?
来讲讲你对ThreadLocal的理解
面试的时候被问到ThreadLocal的相关知识,没有回答好(奶奶的,现在感觉问啥都能被问倒),所以我决定先解决这几次面试中都遇到的高频问题,把这几个硬骨头都能理解的透彻的说出来了,感觉最起码不能总是一轮游。
纪莫
2020/09/11
3390
探索JAVA并发 - ThreadLocal
SimpleDateFormat是我们常用的日期格式化工具,但熟悉的朋友都知道它是线程不安全的。
acupt
2019/08/26
4030
揭秘ThreadLocal
ThreadLocal是开发中最常用的技术之一,也是面试重要的考点。本文将由浅入深,介绍ThreadLocal的使用方式、实现原理、内存泄漏问题以及使用场景。 ThreadLocal作用 在并发编程中时常有这样一种需求:每条线程都需要存取一个同名变量,但每条线程中该变量的值均不相同。 如果是你,该如何实现上述功能?常规的思路如下: 使用一个线程共享的Map<Thread,Object>,Map中的key为线程对象,value即为需要存储的值。那么,我们只需要通过map.get(Thread.curre
大闲人柴毛毛
2018/03/29
1.1K0
揭秘ThreadLocal
服了,一个ThreadLocal被问出了花
地铁上,小帅无力地倚靠着杆子,脑子里尽是刚才面试官的夺命连环问,“用过ThreadLocal么?ThreadLocal是如何解决共享变量访问的安全性的呢?你觉得啥场景下会用到ThreadLocal? 我们在日常用ThreadLocal的时候需要注意什么?ThreadLocal在高并发场景下会造成内存泄漏吗?为什么?如何避免?......”
程序员老猫
2024/02/22
1680
服了,一个ThreadLocal被问出了花
说一说线程局部变量ThreadLocal
通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢? JDK中提供的ThreadLocal类正是为了解决这样的问题。 ThreadLocal类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。
简单的程序员
2020/04/21
8040
说一说线程局部变量ThreadLocal
ThreadLocal分析
ThreadLocal是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。
爱撸猫的杰
2019/08/07
7690
ThreadLocal分析
ThreadLocal 你真的用不上吗?
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/09/19
2720
ThreadLocal 你真的用不上吗?
ThreadLocal
通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢? JDK中提供的ThreadLocal类正是为了解决这样的问题。 ThreadLocal类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。
崔笑颜
2020/06/08
4350
ThreadLocal原理知多少
通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢?JDK 中提供的ThreadLocal类正是为了解决这样的问题。ThreadLocal类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。
黑洞代码
2021/03/19
3890
平时常说的ThreadLocal,今天就彻底解决它
ThreadLocal是多线程处理中非常重要的一个工具,比如数据库连接池存放Connection、存放本地参数等作用,面试也经常会问到它的应用及原理,本文就将从外到内地学习一下ThreadLocal。
beifengtz
2019/07/23
2.3K2
java并发之无同步方案-ThreadLocal
1.ThreadLocal  介绍2.ThreadLocal  应用3.ThreadLocal  源码解析3.1解决 Hash 冲突4.ThreadLocal 特性5.4.ThreadLocal 内存泄露问题
Java宝典
2020/11/30
4030
ThreadLocal - 崔笑颜的博客
通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢? JDK中提供的ThreadLocal类正是为了解决这样的问题。 ThreadLocal类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。
崔笑颜
2021/03/22
4740
ThreadLocal - 崔笑颜的博客
Java多线程:神秘的线程变量 ThreadLocal 你了解吗?
前言 在 Java多线程中,线程变量ThreadLocal非常重要,但对于很多开发者来说,这并不容易理解,甚至觉得有点神秘 今天,我将献上一份 ThreadLocal的介绍 & 实战攻略,希望你们会喜
Carson.Ho
2019/02/22
5180
浅谈ThreadLocal
ThreadLocal顾名思义,线程本地,即各个线程互不干扰的空间,每个线程只能看到当前线程放入的对象。
你的益达
2020/08/14
2790
深入理解ThreadLocal:拨开迷雾,探究本质
本文将带领读者深入理解ThreadLocal,为了保证阅读质量,我们可以先一起来简单理解一下什么是ThreadLocal?如果你从字面上来理解,很容易将ThreadLocal理解为『本地线程』,那么你就大错特错了。首先,ThreadLocal不是线程,更不是本地线程,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。它是每个线程独享的本地变量,每个线程都有自己的ThreadLocal,它们是线程隔离的。接下来,我们通过一个生活案例来开始理解ThreadLocal。
itlemon
2020/03/31
2980
ThreadLocal 原理
从上面可以看出,Thread 类中有一个 threadLocals 和 inheritableThreadLocals 变量,它们都是 ThreadLocalMap 类型的变量,可以把 ThreadLocalMap 理解为ThreadLocal 类实现的定制化的 HashMap。默认情况下,这两个变量都是 null,只有当前线程调用 ThreadLocal 类的 set 或 get 方法时才创建它们,实际上调用这两个方法的时候,真正调用的是 ThreadLocalMap 类对应的 get()、set()方法。
happyJared
2019/07/09
2850
抛出这8个问题,检验一下你到底会不会ThreadLocal,来摸个底~
ThreadLocal类是用来提供线程内部的局部变量。让这些变量在多线程环境下访问(get/set)时能保证各个线程里的变量相对独立于其他线程内的变量。
Java编程指南
2020/07/24
7310
抛出这8个问题,检验一下你到底会不会ThreadLocal,来摸个底~
相关推荐
全面理解ThreadLocal(详细简单)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档