赛普拉斯 12864_使用赛普拉斯在Salesforce中进行测试

赛普拉斯 12864

Salesforce is a Customer Relationship Management (CRM) platform that includes modules for sales, service, marketing, analytics, and more. The tool enables developers to write and execute unit tests through the Apex testing framework. However, if you are either a tester or a developer working with Salesforce, you have probably faced the need for testing a feature in the UI.

Salesforce是一个客户关系管理(CRM)平台,其中包括销售,服务,市场营销,分析等模块。 该工具使开发人员可以通过Apex测试框架编写和执行单元测试。 但是,如果您是使用Salesforce的测试人员或开发人员,则可能已经面临在UI中测试功能的需求。

In this article, I’m going to share some tips to help you create your Salesforce UI testing framework using Cypress, based on the challenges I faced when creating my own. The main advantage of using Cypress, in my opinion, is the ease of set up. Who works with Selenium, for example, knows how time-consuming it can be to define and configure the dependencies before start writing the tests.

在本文中,我将基于创建自己的挑战时,分享一些技巧,以帮助您使用赛普拉斯创建Salesforce UI测试框架。 我认为,使用赛普拉斯的主要优点是易于设置。 例如,谁与Selenium合作,谁知道在开始编写测试之前定义和配置依赖项会是多么耗时。

The goal of this article is not teaching how to use Cypress from the basics. If you’re not familiar with it yet, I recommend the series created by Soraia Fernandes. She provides a solid walk-through on how to create your first project using Page Objects and Cucumber, which is the same approach I like to use.

本文的目的不是从基础上讲授如何使用赛普拉斯。 如果您还不熟悉它,我推荐Soraia Fernandes创建系列 。 她为如何使用Page Objects和Cucumber创建第一个项目提供了扎实的演练,这是我喜欢使用的相同方法。

The examples were tested using the following versions of the dependencies:

使用以下版本的依赖项对示例进行了测试:

"devDependencies": {
"cypress": "4.11.0",
"cypress-xpath": "1.6.0",
"jsforce": "1.9.3"
}

在多个沙箱中测试 (Testing in multiple Sandboxes)

In Salesforce, it’s possible to create copies of the production organization for different purposes, such as development and testing. These copies are called Sandboxes and are isolated from the production org. It means changes made in a Sandbox won’t impact the data or the code in production.

在Salesforce中,可以出于不同目的(例如开发和测试)创建生产组织的副本。 这些副本称为沙盒,并且与生产组织隔离。 这意味着在沙盒中进行的更改不会影响生产中的数据或代码。

Depending on your team’s process, you may need to run your tests in different Sandboxes. Luckily, Cypress provides simple ways of doing it. The one I like the most is having multiple configuration files containing environment variables for each Sandbox.

根据团队的过程,您可能需要在不同的沙箱中运行测试。 幸运的是,赛普拉斯提供了简单的方法。 我最喜欢的一个是有多个配置文件,其中包含每个沙箱的环境变量。

// cypress/config/cypress.test.json{
"baseUrl": "https://mysandbox.test.salesforce.com","env": {
"salesforce": {
"loginUrl" : "https://test.salesforce.com",
"username" : "<my_username>",
"password" : "<my_password>",
"accessToken" : "<my_accessToken>"
}
}
}// cypress/config/cypress.dev.json{
"baseUrl": "https://mysandbox.dev.salesforce.com","env": {
"salesforce": {
"loginUrl" : "https://test.salesforce.com",
"username" : "<my_username>",
"password" : "<my_password>",
"accessToken" : "<my_accessToken>"
}
}
}// cypress/config/cypress.prod.json{
"baseUrl": "https://mysandbox.prod.salesforce.com","env": {
"salesforce": {
"loginUrl" : "https://login.salesforce.com",
"username" : "<my_username>",
"password" : "<my_password>",
"accessToken" : "<my_accessToken>"
}
}
}

To execute the scenarios considering specific configuration files, create scripts for them in the package.json file using the --config-file tag.

要执行考虑特定配置文件的方案,请使用--config-file标记在package.json文件中为它们创建脚本。

// cypress/package.json"scripts": {"cy:open:dev": "cypress open --config-file ./cypress/config/cypress.dev.json","cy:open:test": "cypress open --config-file ./cypress/config/cypress.test.json","cy:run:dev": "cypress run --config-file ./cypress/config/cypress.dev.json","cy:run:test": "cypress run --config-file ./cypress/config/cypress.test.json"}

Open Cypress and go to Settings > Configuration to check the environment variables.

打开赛普拉斯并进入设置>配置以检查环境变量。

yarn run cy:open:test
Image for post
The Environment Variables are displayed in the Configuration section
环境变量显示在“配置”部分中

The environment variables are now available for use in the tests and accessible by using Cypress.env(). There will be a practical use for it in the next topic.

现在可以在测试中使用这些环境变量,并且可以使用Cypress.env()来访问这些环境变量。 在下一个主题中将有实际用途。

登录到Salesforce (Login into Salesforce)

After reading some forums on the topic, I noticed cases in which people gave up using Cypress to test in Salesforce because they faced difficulties to log in. The main mistake, in this case, is probably trying to use the UI for that. When taking such an approach, the following error is displayed:

在阅读了有关该主题的一些论坛之后,我注意到一些人因为登录困难而放弃使用赛普拉斯在Salesforce中进行测试的情况。在这种情况下,主要的错误可能是试图使用UI。 采用这种方法时,将显示以下错误:

Whoops, there is no test to run.
Error in the App Preview
应用预览中的错误

A good practice I like to follow is to don’t use the UI to set up state. Login is a crucial part of the test because it needs to run in every single scenario. So, it makes sense these steps execute as fast as possible. Having this in mind, we can create a login() method using cy.request() to log in and, then, using cy.visit() to open your instance page.

我喜欢遵循的一个好习惯是不要使用UI来设置状态。 登录是测试的关键部分,因为它需要在每个场景中运行。 因此,有意义的是这些步骤应尽可能快地执行。 考虑到这一点,我们可以使用cy.request()登录并随后使用cy.visit()打开实例页面来创建login()方法。

// cypress/support/commands.jsCypress.Commands.add('login', () => {
const loginUrl = Cypress.env("salesforce").loginUrl
const username = Cypress.env("salesforce").username
const password = Cypress.env("salesforce").passwordcy.request(`${loginUrl}/?un=${username}&pw=${password}`)
.then(() => {
cy.visit('/')
})
})

Now, cy.login() is available for use. If the project uses Cucumber, add a Before step to a feature file.

现在,可以使用cy.login() 。 如果项目使用Cucumber,请功能文件中添加“ 之前”步骤。

// cypress/support/step-definitions/common-steps.jsBefore(() => {
cy.login()
})

It’s also possible to use root-level hooks in Mocha. Before every test in the spec files, Cypress will check cypress/support/index.js file, which makes a good idea to place a beforeEach command there.

也可以在Mocha中使用根级挂钩 。 在规范文件中的每个测试之前,赛普拉斯都会检查cypress/support/index.js文件,这是在其中放置一个beforeEach命令的好主意。

// cypress/support/index.jsbeforeEach(() => {
cy.login()
})
Salesforce homepage opened in Cypress during test execution.
User logged in Salesforce in the test execution
用户在测试执行中登录Salesforce

It’s important to have in mind that the IP of the machine or server running Cypress must be whitelisted in Salesforce. Read more on Login IP Whitelist.

重要的是要记住, 必须在Salesforce中将运行Cypress的计算机或服务器的IP列入白名单 。 在登录IP白名单中了解更多信息。

利用jsForce (Taking advantage of jsForce)

Test data is an important element for the success of automation projects. When writing scenarios to test in Salesforce, we need to have Accounts, Products, Opportunities, and the idea of generating this data using the UI might cross our minds. However, as mentioned before, we should not use it to set up a state.

测试数据是自动化项目成功的重要元素。 在编写要在Salesforce中进行测试的方案时,我们需要拥有客户,产品,机会,并且使用UI生成此数据的想法可能会引起我们的注意。 但是,如前所述,我们不应使用它来建立状态。

To help with this issue, we can take advantage of jsForce, a JavaScript Library that utilizes Salesforce’s API. jsForce allows the connection with Salesforce and provides methods to CRUD, query, and much more. To add it to the project, just run:

为了解决这个问题,我们可以利用jsForce ,这是一个利用Salesforce APIJavaScript库。 jsForce允许与Salesforce进行连接,并提供CRUD,查询等方法。 要将其添加到项目中,只需运行:

yarn add jsforce@1.9.3 --dev

The strategy to use jsForce with Cypress will be creating tasks like salesforceCreate(), salesforceUpdate(), salesforceQuery() in cypress/plugins/index.js and using them to add new commands to the project.

将jsForce与Cypress结合使用的策略是在cypress/plugins/index.js创建诸如salesforceCreate()salesforceUpdate()salesforceQuery()类的任务,并使用它们将新命令添加到项目中。

For any of those tasks, firstly it’s necessary to connect and log into Salesforce. jsForce provides several ways of doing that. The chosen here was the Username and Password Login, as the credentials are available in the environment variables.

对于任何这些任务,首先必须连接并登录到Salesforce 。 jsForce提供了几种方法。 由于环境变量中提供了凭据,因此此处选择的是用户名和密码登录

The following example makes use of the jsForce method create. It allows the creation of one or more records of the type given in the first argument: objectType. It’s valid to highlight that all the environment variables are accessible from cypress/plugins/index.js. However, Cypress.env() won’t work, making us use config.env instead.

以下示例使用jsForce方法create 。 它允许创建第一个参数objectType指定类型的一个或多个记录。 突出显示可以从cypress/plugins/index.js访问所有环境变量是有效的。 但是, Cypress.env()无法正常工作,因此我们改用config.env

// cypress/plugins/index.jsconst jsforce = require('jsforce');/**
*
* @param {string} objectType Type of the object to be created, e.g., 'Account', 'Opportunity', 'Product2'
* @param {*} object Salesforce object specificification, e.g., { Name: 'Test Account', Phone: '0123456789' }
* @param {*} config
*/
function createObject(objectType, object, config) {const username = config.env.salesforce.username
const password = config.env.salesforce.password
+ config.env.salesforce.accessToken
const loginUrl = config.env.salesforce.loginUrlreturn new Promise((resolve, reject) => {
var conn = new jsforce.Connection({loginUrl: loginUrl})conn.login(username, password, err => {
if (err) reject(err)conn.sobject(objectType).create(object, (err, ret) => {
if (err || !ret.success) { return console.error(err, ret) }console.log(`Created ${objectType} with id : ${ret.id}`)
return resolve(ret)})
})
})
}module.exports = (on, config) => {
on('task', {
salesforceCreate ({objectType, object}) {
return createObject(objectType, object, config)
},
// Add new tasks created here
}
}

The next step is to add a new command, e.g., createAccount().

下一步是添加一个新命令,例如createAccount()

// cypress/support/commands.jsCypress.Commands.add('createAccount', (obj) => {
cy.task('salesforceCreate', ({objectType: 'Account', object: obj}))
})

All setup! Now the new command can be used in the test file.

全部设置! 现在,可以在测试文件中使用新命令。

// your/test/file.jscy.createAccount(
.then((newAccount) => {
cy.wrap(newAccount.id).as('newAccountId')
})

The jsForce documentation is quite complete. Refer to it whenever you need new methods in your project.

jsForce文档非常完整。 在项目中需要新方法时,请参考它。

有关创建对象的建议... (A suggestion for creating objects…)

When creating new objects, we generally need them to have specific values to attend our needs in a given scenario. For such, a nice strategy is to create classes to represent Salesforce objects, such as Account or Opportunity, and define the Field API Names as instance variables.

在创建新对象时,我们通常需要它们具有特定的值来满足给定场景中的需求。 为此,一个不错的策略是创建代表Salesforce对象的类,例如Account或Opportunity,并将Field API Names定义为实例变量。

// cypress/domain/account.jsexport class Account {AccountNumber
City__c
Country__c
Id
Phone
RecordTypeIdsetAccountNumber = (accountNumber) => {
this.AccountNumber = accountNumber
}setCity = (city) => {
this.City__c = city
}setCountry = (country) => {
this.Country__c = country
}setId = (id) => {
this.Id = id
}setPhone = (phone) => {
this.Phone = phone
}setRecordTypeId = (recordTypeId) => {
this.RecordTypeId = recordTypeId
}
}

In the test file, we can instantiate an object and set values to it as needed. Then, use it to, for example, create a Salesforce Object.

在测试文件中,我们可以实例化一个对象并根据需要为其设置值。 然后,使用它来创建一个Salesforce对象。

// your/test/file.jsimport { Account } from "path/to/class/account"const account = new Account()account.setAccontNumber("123456")
account.setCity("Tokyo")
account.setCountry("Japan")cy.salesforceCreateAccount(
.then((newAccount) => {
cy.wrap(newAccount.id).as('newAccountId')
})

使用XPath选择元素 (Selecting elements with XPath)

If you have already tried writing automation tests in Salesforce, you probably know that using DOM id’s when selecting elements is not the best approach as they constantly change. To avoid this problem, a solution that has proven to be very satisfactory in my tests is to write selectors using the relative XPath with the field label in it.

如果您已经尝试过在Salesforce中编写自动化测试,则可能知道在选择元素时使用DOM id并不是最好的方法,因为它们会不断变化。 为避免此问题,一种在我的测试中被证明非常令人满意的解决方案是使用带有字段标签的相对XPath编写选择器。

const nameField = `//*[text()='Name']/parent::span/following-sibling::div[1]//a`

This approach has some advantages:

这种方法有一些优点:

  • Risk reduction of an element not being found during the test execution;

    降低在测试执行过程中找不到元素的风险;
  • Improvement on the selector’s readability;

    提高选择器的可读性;
  • Better maintainability.

    更好的可维护性。

To use XPath in Cypress, add a Custom Command plugin called cypress-xpath to the project.

要在赛普拉斯中使用XPath,请向项目添加一个名为cypress-xpath的自定义命令插件。

yarn add cypress-xpath --dev

Include it to cypress/support/index.js

将其包含在cypress/support/index.js

// cypress/support/index.jsrequire('cypress-xpath')

The class below uses XPath to select the Account page elements.

下面的类使用XPath选择“帐户”页面元素。

// your/page/object/file.jsconst accountNumberField = `//*[text()='Category']/parent::span/following-sibling::div[1]//a`
const cityField = `//*[text()='City']/parent::label/following-sibling::input`
const countryField = `//*[text()='Country']/parent::label/following-sibling::input`
const phoneField = `//*[text()='Phone']/parent::label/following-sibling::input`export class AccountPage {typeAccountNumber(accNumber) {
cy.xpath(accountNumberField)
.clear()
.type(accNumber)
}typeCity(city) {
cy.xpath(cityField)
.clear()
.type(city)
}typeCountry(country) {
cy.xpath(countryField)
.clear()
.type(country)
}typePhone(phone) {
cy.xpath(phoneField)
.clear()
.type(phone)
}
}

结论 (Conclusion)

I hope this article helped you to bypass some initial difficulties to start your Salesforce UI automation framework in Cypress. If you have different strategies, suggestions, or difficulties not listed here, feel free leave comment. We may be able to help each other.

我希望本文能帮助您绕开最初遇到的困难,以在赛普拉斯中启动Salesforce UI自动化框架。 如果您有此处未列出的其他策略,建议或困难,请随时发表评论。 我们也许可以互相帮助。

翻译自: https://medium.com/smartbox-engineering/using-cypress-to-test-in-salesforce-a0699afe09b7

赛普拉斯 12864

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值