1 Windows下安装
1.1方法一
1)安装node.js(https://nodejs.org/en/download/),根据版本选择32位或64位。
2)确认ndejs和npm是否安装上:
C:\Users\xiang>node -v v12.18.0 C:\Users\xiang>npm -v 6.14. |
3)生成package.json(假设准备安装在c:\Cypress>)
C:\Users\xiang>cd c:\Cypress C:\Cypress>npm init |
4)安装Cypress
C:\Cypress>npm install cypress --save-dev |
我按照这种方法安装失败。
1.2方法二
1)安装yarn (https://yarnpkg.com/en/docs/install#windows-stable)
2)确认yarn是否安装上
C:\Users\xiang>yarn -v 1.22.4 |
3)安装Cypress
C:\Users\xiang>cd c:\Cypress C:\Cypress>yarn add cypress --dev |
2. 运行
2.1方法一
C:\Cypress\node_modules\.bin>cypress open |
2.2方法二
C:\Cypress>yarn run cypress open |
2.3 方法三(我经常用的方法)
配置C:\Cypress\package.json
{ "license": "ISC", "scripts": { "cypress:open": "cypress open", "cypress:run": "cypress run" }, "devDependencies": { "cypress": "^4.8.0" } } |
打开运行控制器
C:\Cypress>yarn run cypress open |
运行默认路径下的所有测试代码
C:\Cypress>yarn run cypress run |
默认路径为C:\Cypress\cypress\integration,可以通过
{ … "integrationFolder": "cypress/integration/demo", … } |
改变默认路径,上述代码中默认路径改为C:\Cypress\cypress\integration\demo
3测试框架
before():相当于unittest中的def setUp(cls)方法或者Junit的@Before方法标签;
after():相当于unittest中的 def teardown(cls) 方法或者Junit的 @Before方法标签;
beforeEach() : 相当于unittest中的def setUpClass(cls) 方法或者Junit的@BeforeClass方法标签;
afterEach() : 相当于unittest中的def tearDownClass(cls) 方法或者Junit的@AfterClass方法标签。
4 GUI测试代码案例
4.1 第一个测试代码
测试电子商务系统登录程序
describe('login',function(){ const username = 'cindy' const password = '123456' context('测试电子商务网站',function(){ it('登录成功,调到商品列表页面',function(){ cy.visit('http://127.0.0.1:8000') cy.get('input[name=username]').type(username) cy.get('input[name=password]').type(password) cy.get('form').submit() //断言 cy.url().should('include','/goods_view') cy.get('title').should('contain','电子商务系统') }) }) }) |
4.2元素查找 - get
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off"> |
根据元素 id 查找:cy.get('#kw')
根据元素名称查找:cy.get('input[name="wd"]')
根据元素的类名查找:cy.get('.s_ipt')
根据CSS selector查找:cy.get('input[maxlength ="100"]')
4.3元素查找 – contains
根据元素文本查找:cy.contains('value')
根据元素属性及其文本查找:cy.get('div[name="ele-name"]').contains('value')
使用正则匹配元素文本以查找:cy.get('.class-name').contains(/[0-9]*/)
4.4 操作
type(String)、输入,比如:cy.get('#kw'). type('Testing')
click()、点击,比如:cy.get('.btn'). click ()
clear()、清空input或textarea的内容,比如:cy.get('.ant-input').clear()
submit()、提交表单,比如:cy.get('.ant-form').submit()
dblclick()、元素双击,比如:cy.get('.ant-btn').dblclick()
rightclick()、元素右击,比如:cy.get('.ant-btn').rightclick()
select(String)、对<select>元素选择,比如:cy.get('.ant-select').select('apples')
check()、勾选checkbox,比如:cy.get('.ant-checkbox').check()
Uncheck、反选 checkbox,比如:cy.get('.ant-checkbox').uncheck()
scrollIntoView()、如果某个元素不在当前可视范围,可以滑动至可视范围,比如:cy.get('#id').scrollIntoView()
scrollTo(String)、指定位置滑动,比如:cy.scrollTo('bottom')、cy.get('#id').scrollTo(250, 250)
4.5 鼠标操作
鼠标悬停事件:
cy.get('button').trigger('mouseover')
鼠标按下:
cy.get('button').trigger('mousedown')
鼠标抬起:
cy.get('button').trigger('mouseleave')
cy.get('button').trigger('mouseup')
鼠标长按事件:
cy.get('button').trigger('mousedown')
cy.wait(1000)
cy.get('button').trigger('mouseleave')
鼠标拖拽事件
cy.get('[data-cy=draggable]')
.trigger('mousedown', { which: 1, pageX: 600, pageY: 100 })
.trigger('mousemove', { which: 1, pageX: 600, pageY: 600 })
.trigger('mouseup')
describe('baidu',function(){ context('测试百度网站',function(){ it('查询成功',function(){ cy.visit('https://www.baidu.com') cy.get('input[name=wd]').type("软件测试") cy.get('#su').click() cy.get('title').should('contain','百度搜索') }) it('进入高级查询成功',function(){ cy.get('a[name=tj_settingicon]').trigger('mouseover') cy.get('.bdpfmenu').should('exist') }) }) }) |
4.6 断言
针对长度的断言:cy.get('li.selected').should('have.length',3)
正对类的断言:cy.get('from').fijd('input').should('not.have.class','disabled')
针对值断言:cy.get('textarea').should('have.value','3testing')
针对文本内容的断言:cy.get('a').parent('span.help').should('contain','click me')
针对元素可见与否的断言:cy.get('button').should('be.visible')
针对元素存在与否的断言:cy.get('#loading').should('not.exist')
针对元素状态的State的断言:cy.get(':radio').should('be.checked')
针对CSS的断言:cy.get('.completed').should('have.css','text-decoration','line-through')
4.7 跨iframe操作
describe('login',function(){ context('测试啄木鸟软件咨询网',function(){ it('点击我的介绍成功',function(){ cy.visit('http://www.3testing.com') cy.get('#head',{timeout: 2000}) .then($iframe => { cy.wrap($iframe.contents().find("#introduce")); }) .then($btn => { cy.wrap($btn).click() }); //断言 cy.url().should('include','introduce.html') cy.get('title').should('contain','啄木鸟软件测试咨询网-顾翔介绍') }) }) }) |
4.8 多窗口操作
Cypress不支持多窗口操作。
5 API测试
5.1 普通API测试
describe('login',function(){ const username = 'cindy' const password = '123456' const producturl="http://127.0.0.1:8000/login_action/" cy.request({ method: 'POST', url: producturl, body: { username: username password: password } }) }) |
5.2 CSRF token API测试
describe('login',function(){ const username = 'cindy' const password = '123456' const producturl="http://127.0.0.1:8000/login_action/" Cypress.Commands.add('loginByCSRF', (csrfToken) => { cy.request({ method: 'POST', url: producturl, failOnStatusCode: false, // 不要失败,这样我们才能断言 form: true, // 我们正在提交一份常规表格 body: { username, password, csrfmiddlewaretoken: csrfToken // 将此作为主体的一部分插入 } }) }) // csrf在返回的html中,我测试的Django产品的CSRF token用这种方法 it('策略#1:从HTML解析令牌', function(){ // 如果我们不能改变我们的服务器代码以使解析CSRF令牌变得更容易, // 我们可以简单地使用cy.request来获取登录页面,然后解析HTML内容 // 以找到嵌入在页面中的CSRF令牌 cy.request(producturl) .its('body') .then((body) => { //我们可以用Cypress.$解析字符串主体,从而使我们能够轻松地查询到它 cy.log(body) const $html = Cypress.$(body) const csrf = $html.find("input[name=csrfmiddlewaretoken]").val() cy.loginByCSRF(csrf) .then((resp) => { expect(resp.status).to.eq(200) expect(resp.body).to.contain("Company 2017") }) }) }) }) /* // 如果csrf在响应头中 it('策略#2:从响应头解析令牌', function(){ // 如果我们将csrf令牌嵌入到响应头中,那么我们就可以更容易地提取它, // 而不必深究最终的HTML cy.request(producturl) .its('headers') .then((headers) => { const csrf = headers['csrftoken'] cy.log(csrf) cy.loginByCSRF(csrf) .then((resp) => { expect(resp.status).to.eq(200) expect(resp.body).to.contain("Company 2017") }) }) }) }) */ |
版权声明:本文出自51Testing会员投稿,51Testing软件测试网及相关内容提供者拥有内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。