catcher.exe_使用Catcher从前端到后端进行端到端

catcher.exe

Catcher’s external modules 5.1.0 were finally released. It’s great news as it enables Selenium step for Front-end testing!

麦田守望者》的外部模块5.1.0终于发布了。 这是一个好消息,因为它使Selenium步骤可以进行前端测试!

正确的e2e测试应该如何? (How should proper e2e test look like?)

Imagine you have a user service with nice UI, which allows you to get information about users, registered in your system. Deeply in the back-end you also have an audit log, which saves all actions.

想象一下,您有一个具有漂亮UI的用户服务,该服务使您可以获取有关已在系统中注册的用户的信息。 在后端深处,您还具有审核日志,该日志保存所有操作。

Image for post

Before 5.1.0 you could use HTTP calls to mimic front-end behavior to trigger some actions on the back-end side.

5.1.0之前,您可以使用HTTP调用来模仿前端行为,以触发后端方面的某些操作。

Your test probably looked like:- call http endpoint to search for a user- check search event was saved to the database- compare found user with search event, saved in the database

您的测试可能看起来像:-调用http端点以搜索用户-检查搜索事件是否已保存到数据库中-将找到的用户与搜索事件进行比较,并保存在数据库中

This test checks 100% of back-end functionality. But most likely front-end is the part of your system also! So proper end-to-end test should start with front-end application and end up in a back-end.

此测试检查100%的后端功能。 但是最有可能的前端也是您系统的一部分! 因此, 正确的端到端测试应从前端应用程序开始,然后在后端进行

Without touching front-end you could have false-positive results in e2e tests. F.e.: a user has some special symbols in his name. All back-end tests passes and you deploy your application in production. After the deploy your users start to complain that front-end part of the application crashes. The reason is — front-end can’t handle back-end’s response when rendering user details with special symbols in his name.

不接触前端,您可能会在e2e测试中得到假阳性结果。 Fe:用户的名字中有一些特殊符号。 所有后端测试均通过,您可以在生产环境中部署应用程序。 部署后,您的用户开始抱怨应用程序的前端部分崩溃。 原因是-呈现用户名称中带有特殊符号的用户详细信息时,前端无法处理后端的响应。

With the new Catcher’s version you can include Front-end in your test. So — instead of calling http you can use selenium step.

使用新的Catcher版本,您可以在测试中包括前端。 因此,您可以使用Selenium步骤来代替调用http。

考试 (The test)

Let’s write a test, which will search for a user and will check that our search attempt was logged.

让我们编写一个测试,该搜索将搜索用户并检查是否记录了我们的搜索尝试。

Every test starts with variables. To cover false-positive results we need to save multiple users and then check that only the correct one is returned. Let’s compose our users. Every user will have a random email and random name thanks to random built-in function.

每个测试都从变量开始。 为了覆盖假阳性结果,我们需要保存多个用户,然后检查是否只返回了正确的用户。 让我们组成我们的用户。 借助内置的随机功能,每个用户都将拥有一个随机的电子邮件和一个随机的名称。

variables: 
users:
- name: '{{ random("name") }}'
email: '{{ random("email") }}'
- name: '{{ random("name") }}'
email: '{{ random("email") }}'
- name: '{{ random("name") }}'
email: '{{ random("email") }}'

Now we are ready to write our steps.

现在我们准备好编写steps

填充数据 (Populate the data)

The first step we need to do is to populate the data with prepare step.

我们需要做的第一步是用准备步骤填充数据。

Let’s prepare a users.sql which will create all back-end tables (in case of clean run we don't have them).

让我们准备一个users.sql ,它将创建所有后端表(在干净运行的情况下,我们没有它们)。

CREATE TABLE if not exists users_table( 
email varchar(36) primary key,
name varchar(36) NOT NULL
);

Next — we need to fill our table with test data. users.csv will use our users variable to prepare data for our step.

接下来-我们需要在表中填写测试数据。 users.csv将使用我们的users变量为我们的步骤准备数据。

email,name 
{%- for user in users -%}
{{ user.email }},{{ user.name }}
{%- endfor -%}

The step itself will take users.sql and create database tables if needed. Then it will populate it using users.csv based on users variable.

该步骤本身将使用users.sql并在需要时创建数据库表。 然后,它将根据users变量使用users.csv填充。

steps: 
- prepare:
populate:
postgres:
conf: '{{ postgres }}'
schema: users_table.sql
data:
users: users.csv
name: Populate postgres with {{ users|length }} users

选择要搜索的用户 (Select a user to search for)

The next (small) step is to select a user for our search. Echo step will randomly select user from users variable and register it's email as a new variable.

下一步(小步骤)是选择一个用户进行搜索。 回显步骤将从users变量中随机选择用户,并将其电子邮件注册为新变量。

- echo: 
from: '{{ random_choice(users).email }}'
register: {search_for: '{{ OUTPUT }}'}
name: 'Select {{ search_for }} for search'

在前端搜索我们的用户 (Search front-end for our user)

With the Selenium step we can use our front-end to search for the user. Selenium step runs the script in JS/Java/Jar/Python from resources directory.

通过Selenium步骤,我们可以使用前端来搜索用户。 Selenium步骤从资源目录在JS / Java / Jar / Python中运行脚本。

It passes Catcher’s variables as environment variables to the script so you can access it within Selenium. It also greps the script’s output, so you can access everything in Catcher’s next steps.

它将Catcher的变量作为环境变量传递到脚本,以便您可以在Selenium中访问它。 它还可以掌握脚本的输出,因此您可以访问Catcher下一步中的所有内容。

- selenium: 
test:
file: register_user.js
driver: '/usr/lib/geckodriver'
register: {title: '{{ OUTPUT.title }}'}

The script will run register_user which searches for our selected user and will register page’s title.

该脚本将运行register_user,该脚本搜索我们选择的用户并注册页面标题。

检查搜索日志 (Check the search log)

After we did the search we need to check if it was logged. Imagine our back-end uses MongoDB. So we’ll use mongo step.

搜索完成后,我们需要检查是否已记录。 想象一下我们的后端使用MongoDB。 因此,我们将使用mongo步骤。

- mongo: 
request:
conf: '{{ mongo }}'
collection: 'search_log'
find: {'text': '{{ search_for }}'}
register: {search_log: '{{ OUTPUT }}'}

This step searches MongoDB search_log collection for any search attempts with our user in text.

此步骤在MongoDB search_log集合中搜索与我们的用户进行文本搜索的任何尝试。

比较结果 (Compare results)

Final steps are connected with results comparison. First — we’ll use echo again to transform our users so that we can search in users by email.

最后的步骤与结果比较相关。 首先-我们将再次使用echo来转换users以便我们可以通过电子邮件搜索用户。

- echo: 
from: '{{ users|groupby("email")|asdict }}'
register: {users_kv: '{{ OUTPUT }}'}

Second — we will compare front-end page title got from selenium with MongoDB search log and user’s name.

其次-我们将从Selenium中获取的前端页面标题与MongoDB搜索日志和用户名进行比较。

- check: 
and:
- equals: {the: '{{ users_kv[search_for][0].name }}', is: '{{ title }}'}
- equals: {the: '{{ title }}', is: '{{ search_log.name }}'}

Selenium资源 (The selenium resource)

Let’s add a Selenium test resource. It will go to your site and will searches for your user. If everything is OK page title will be the result of this step.

让我们添加一个Selenium测试资源。 它将转到您的站点并搜索您的用户。 如果一切正常,页面标题将是此步骤的结果。

Java脚本 (Javascript)

Selenium step supports Java, JS, Python and Jar archives. In this article I’ll show you all of them (except Jar, it is the same as Java, but without compilation). Let’s start with JavaScript.

Selenium步骤支持Java,JS,Python和Jar存档。 在本文中,我将向您展示所有它们(Jar除外,它与Java相同,但没有编译)。 让我们从JavaScript开始。

const {Builder, By, Key, until} = require('selenium-webdriver');
async function basicExample() {
let driver = await new Builder().forBrowser('firefox').build();
try{
await driver.get(process.env.site_url);
await driver.findElement(By.name('q')).sendKeys(process.env.search_for, Key.RETURN);
await driver.wait(until.titleContains(process.env.search_for), 1000);
await driver.getTitle().then(function(title) {
console.log('{\"title\":\"' + title + '\"}')
});
driver.quit();
}
catch(err) {
console.error(err);
process.exitCode = 1;
driver.quit();
}
}
basicExample();

Catcher passes all it’s variables as environment variables, so you can access them from JS/Java/Python. process.env.site_url in this example takes site_url from Catcher's variables and process.env.search_for takes user email to search for it.

Catcher将所有变量传递为环境变量,因此您可以从JS / Java / Python访问它们。 process.env.site_url在这个例子中需要从麦田的变量SITE_URL和process.env.search_for需要用户的电子邮件搜索它。

Everything you write to STDOUT is caught by Catcher. In case of JSON it will be returned as dictionary. F.e. with console.log('{\"title\":\"' + title + '\"}') statement OUTPUT.title will be available on Catcher's side. If Catcher can't parse JSON - it will return a text as OUTPUT.

您写入STDOUT的所有内容都会被Catcher捕获。 如果是JSON,它将作为字典返回。 Fe带有console.log('{\"title\":\"' + title + '\"}')语句OUTPUT.title将在Catcher侧可用。 如果Catcher无法解析JSON-它将返回一个文本为OUTPUT

Python (Python)

Here is the Python implementation of the same resource. It should be also placed in resources directory. To use it instead of Java implementation you need to change file parameter in Selenium step.

这是相同资源的Python实现。 它也应该放在resources目录中。 要使用它代替Java实现,您需要在Selenium步骤中更改file参数。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import os
from selenium.webdriver.firefox.options import Options
options = Options()
options.headless = True
driver = webdriver.Firefox(options=options)
try:
driver.get(os.environ['site_url'])
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys(os.environ['search_for'])
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
print(f'{"title":"{driver.title}"')
finally:
driver.close()

Java (Java)

Java is a bit more complex, as (if you are not using already compiled Jar) Catcher should compile Java source before running it. For this you need to have Java and Selenium libraries installed in your system.

Java稍微复杂一点,因为(如果您不使用已编译的Jar),Catcher应该在运行Java源代码之前先对其进行编译。 为此,您需要在系统中安装Java和Selenium库。

Luckily Catcher comes with Docker image where libraries (JS, Java, Python), Selenium drivers (Firefox, Chrome, Opera) and tools (NodeJS, JDK, Python) installed.

幸运的是Catcher附带了Docker 映像 ,其中安装了库(JS,Java,Python),Selenium驱动程序(Firefox,Chrome,Opera)和工具(NodeJS,JDK,Python)。

package selenium;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxOptions;
public class MySeleniumTest {
public static void main(String[] args) {
FirefoxBinary firefoxBinary = new FirefoxBinary();
FirefoxOptions options = new FirefoxOptions();
options.setBinary(firefoxBinary);
options.setHeadless(true);
WebDriver driver = new FirefoxDriver(options);
try {
driver.get(System.getenv("site_url"));
WebElement element = driver.findElement(By.name("q"));
element.sendKeys(System.getenv("search_for"));
element.submit();
System.out.println("{\"title\":\""+driver.getTitle() + "\"}");
} finally {
driver.quit();
}
}
}

结论 (Conclusion)

Catcher’s update 5.1.0 unites front and back-end testing, allowing them both to exist in one testcase. It improves the coverage and make the test really end-to-end.

Catcher的更新5.1.0将前端和后端测试结合在一起,使它们都可以存在于一个测试用例中。 它提高了覆盖范围,并使测试真正端到端。

翻译自: https://itnext.io/end-to-end-from-front-end-to-back-end-with-catcher-c6d8e0388258

catcher.exe

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值