簡體   English   中英

設置測試數據以對單頁Web應用程序及其后端進行全棧測試

[英]Setting up test data for full-stack testing of a single page web application and its back-end

我的問題的簡短版本

在為Angular單頁Web應用程序編寫的Cucumber測試中,我如何完成通常在場景的“給定”部分中執行的任務(例如設置測試數據,定義數據庫記錄關聯以及確保測試之間的數據庫狀態干凈) )在測試全棧時,前端應用程序及其后端? 應用程序源代碼存儲在兩個單獨的Git存儲庫中,一個用於前端應用程序,一個用於后端。 后端是使用Rails API gem用Ruby編寫的。 全棧測試該應用程序所面臨的挑戰來自這樣一個事實,即它實際上是兩個應用程序,而不是傳統的Ruby on Rails應用程序未實現為單頁應用程序。

我的問題的完整版本

我正在為Web應用程序編寫一系列的Cucumber測試。 該應用程序由用Angular編寫的前端單頁應用程序和使用Rails API編寫的后端API組成。 前端的源代碼和后端的源代碼分別位於各自的Git存儲庫中,從而在兩個代碼庫之間提供了清晰的分隔。 此外,該應用程序使用MySQL和Elasticsearch。

過去,我在先前的Ruby on Rails項目中使用過Cucumber。 這些項目不是作為單頁應用程序開發的。 在這些項目中,很容易在cumberber步驟定義中創建Ruby對象作為測試數據。 例如,考慮不是單個頁面應用程序的Rails項目中的以下功能文件:

# features/home_page.feature
Feature: Home page

  Scenario: Viewing application's home page
    Given there's a post titled "My first" with "Hello, BDD world!" content
    When I am on the homepage
    Then I should see the "My first" post

可以使用以下步驟定義來實現此功能文件中的步驟:

# features/step_definitions/home_page_steps.rb
Given(/^there's a post titled "(.*?)" with "(.*?)" content$/) do |title, content|
  @post = FactoryGirl.create(:post, title: title, content: content)
end

When(/^I am on the homepage$/) do
  visit root_path
end

Then(/^I should see the "(.*?)" post$/) do |title|
  @post = Post.find_by_title(title)

  page.should have_content(@post.title)summary of the question
  page.should have_content(@post.content)
end

在不是作為單頁應用程序開發的Ruby on Rails項目中,測試工具可以作為Ruby gems包含在項目中。 對我來說,這些工具包括:

group :test do
  gem 'shoulda-matchers'
  gem 'cucumber-rails', require: false
  gem 'database_cleaner'
  gem 'selenium-webdriver'
end

group :development, :test do
  gem 'factory_girl_rails'
end

如您所見,這包括用於將Ruby對象設置為測試數據並定義數據庫記錄關聯的Factory Girl,以及用於確保測試之間的干凈數據庫狀態的Database Cleaner。 使用JavaScript的Cucumber方案要求包含Selenium WebDriver。

對於我的單頁應用程序,情況有所不同。 如上所述,該應用程序分為兩個單獨的代碼庫,一個用於Angular前端單頁應用程序,另一個用於Rails API后端接口。

但是,像我的項目這樣的單頁應用程序仍然具有與不作為單頁應用程序構建的更傳統的Rails應用程序相同的測試要求。 有必要對應用程序進行全棧測試,以確保前端和后端的每個組件都能按預期工作。 在測試之前,需要定義黃瓜步驟以創建“給定的”前提,並且有必要確保測試之間的數據庫干凈。

如何使用Cucumber測試這樣的應用程序(一個具有兩個代碼庫的應用程序)實現為單頁應用程序? 有一個適用於JavaScript的Cucumber版本,稱為CucumberJS。 但是,我不知道如何使用CucumberJS創建固定裝置,記錄關聯以及如何確保測試之間的干凈數據庫。 還有一個用於測試用Angular編寫的JavaScript的工具,稱為Protractor。 我想象該工具將取代Selenium WebDriver。

回答簡短版本問題。

全棧測試該應用程序的挑戰來自以下事實:它實際上是兩個應用程序

您所描述的內容對單頁應用程序來說是典型的。 我有很多spa示例(用E2E覆蓋),其中后端是PHP,Dot.net或雲Web服務(parse.com)中的RESTful API。 以我的觀點,最好將此類應用程序視為2個不同的應用程序,並為每個應用程序編寫2套不同的測試集。 我相信這是編寫穩定,可擴展和快速的e2e測試的唯一方法。

基本上,我們要做的是創建一個本地的非持久性模擬API(使用javascript),專門用於測試。 以下是此類api的要求/指南列表:

  1. 提供測試服的模擬數據(已讀取-結合測試服)
  2. 僅介紹使測試通過的足夠方法。
  3. 它是非持久性的(請求參數是做出響應的全部,盡管可以有例外)。 所有持久性都在客戶端上(本地存儲,cookie)。 這很重要,因為只需清除客戶端存儲並刷新頁面即可-您將獲得應用程序的全新狀態! 在測試整體的地方-您必須清除並重新填充數據庫,這浪費時間並且完全不可擴展。
  4. 嵌入角度存儲庫中,它是測試套件和開發過程的一部分。

實際情況如何。 假設我們正在測試網站的登錄功能,並且它具有3種情況:

var homepage = require('pages/homepage'); //page object for home page

describe('Authentication', function () {

  beforeEach(function () {
    browser.manage().deleteAllCookies(); //clear persistance
    browser.refresh(); //refresh page
    homepage.get(); //go to homepage
  });

  it('should show error when user enters wrong credentials', function () {
    homepage.signIn('admin', '123'); //submit invalid credentials 
    expect(browser.getCurrentUrl()).toMatch('/home$');    
    expect(homepage.getSignInForm()).toContain('wrong credentials');
  });

});

為了滿足這些測試,我們要做的就是為POST / login請求實現一個api:

router.get('/login', function (req, res) {
  var username = req.body.username, password = req.body.password;

  if (password !== 'admin') {
    res.status(404).json({"error": "wrong credentials"});
  } else {
    res.json(User(username}));
  }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM