小心使用狀態
狀態會使您的步驟更緊密地耦合在一起,並且更難以重複使用。
不要這樣做。
情境必須彼此獨立,因此重要的是,情境之間不共享狀態。不小心將狀態從一個情境洩漏到其他情境,會使您的情境變得脆弱,並且也難以單獨執行。
為了防止意外洩漏情境之間的狀態
Before
鉤子中清除資料庫。Before
鉤子中刪除 Cookie。在您的情境中,您可能想要在步驟之間共享狀態。
可以在步驟定義內的變數中儲存狀態。
Cucumber 將在每個情境之前建立一個新的膠合程式碼類別實例,因此您的步驟不會洩漏狀態。
ScenarioScope
可用於任何已用於共享步驟狀態的 Spring bean;此註釋確保這些 bean 不會跨情境持續存在,因此不會洩漏狀態。ScenarioScoped
應該始終在步驟定義類別中使用。另請參閱依賴注入。
Cucumber 將在每個情境之前建立一個新的膠合程式碼類別實例,因此您的步驟不會洩漏狀態。
ScenarioScope
可用於任何已用於共享步驟狀態的 Spring bean;此註釋確保這些 bean 不會跨情境持續存在,因此不會洩漏狀態。ScenarioScoped
應該始終在步驟定義類別中使用。另請參閱依賴注入。
在 Ruby 中,Cucumber 在 World
中執行情境。預設情況下,World
是 Object
的實例。
所有步驟定義都將在目前 World
實例的上下文中執行;為每個情境建立一個新的實例。這表示步驟定義區塊中的 self
將是 World
實例。在步驟定義中實例化的任何 @instance_variable
都將分配給 World
,並且可以從其他步驟定義存取。
如果您想在世界中新增任何行為,例如輔助方法或記錄,您可以在 support/env.rb
中執行此操作
module CustomWorld
def a_helper
...
end
end
World(CustomWorld)
現在您可以從您的步驟定義中呼叫 a_helper
。
請注意,每個情境都在世界的一個獨立實例中執行,因此沒有從情境到情境的隱式狀態共享。
您也可以在您的 World
中包含模組
module MyHelper
def some_other_helper
...
end
end
module CustomWorld
include MyHelper
def a_helper
...
end
end
World(CustomWorld)
其他幾個框架(例如 Rspec 或 Webrat)都有模組,提供您可以通過這種方式包含在您的 World
中的特殊方法。
如果您不想定義自己的 World
類別(而只是使用預設的 Object
實例),您仍然可以在您的 World
實例中包含模組,而不會使用全域包含污染 Object
module MyHelper
def some_other_helper
...
end
end
module MyOtherHelpers
def helper_b
...
end
end
World(MyHelper, MyOtherHelpers)
這將使用這些模組 extend
每個新的 World
物件。
如果您使用Ruby on Rails,則已經為您設定了一個 World
,因此您將獲得 Cucumber::Rails::World
的實例,它是 ActionDispatch::IntegrationTest
的子類別。這使您可以存取許多 Rails 的輔助方法。
Cucumber-js 使用 World
作為每個情境的隔離上下文。您可以在GitHub 上 cucumber-js 的文件中找到更多資訊。
如果您的程式語言是 JVM 語言,您將在類別中編寫膠合程式碼(步驟定義和鉤子)。
Cucumber 將在每個情境之前建立一個新的膠合程式碼類別實例。
如果您的所有膠合程式碼類別都有一個空的建構函式,則您不需要其他任何東西。但是,大多數專案將受益於依賴注入 (DI) 模組,以更好地組織您的程式碼並在步驟定義之間共享狀態。
可用的依賴注入模組包括
如果您的程式語言是 JVM 語言,您將在類別中編寫膠合程式碼(步驟定義和鉤子)。
Cucumber 將在每個情境之前建立一個新的膠合程式碼類別實例。
如果您的所有膠合程式碼類別都有一個空的建構函式,則您不需要其他任何東西。但是,大多數專案將受益於依賴注入 (DI) 模組,以更好地組織您的程式碼並在步驟定義之間共享狀態。
可用的依賴注入模組包括
要使用 PicoContainer,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-picocontainer', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。有關更多資訊,請參閱使用 PicoContainer 共享狀態。
要使用 PicoContainer,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-picocontainer', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。有關更多資訊,請參閱使用 PicoContainer 共享狀態。
要使用 Spring,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-spring', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。
要使用 Spring,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-spring', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。
要使用 Guice,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-guice</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-guice', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。有關更多資訊,請參閱使用 Guice 共享狀態。
要使用 Guice,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-guice</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-guice', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。有關更多資訊,請參閱使用 Guice 共享狀態。
要使用 OpenEJB,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-openejb</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-openejb', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。
要使用 OpenEJB,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-openejb</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-openejb', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。
要使用 Weld,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-weld</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-weld', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。
要使用 Weld,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-weld</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-weld', version: '7.20.1'
目前沒有文件,但是程式碼在GitHub上。
要使用 Needle,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-needle</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-needle', version: '7.20.1'
目前尚無文件,但程式碼位於 GitHub 上。
要使用 Needle,請將以下依賴項新增至您的 pom.xml
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-needle</artifactId>
<version>7.20.1</version>
<scope>test</scope>
</dependency>
或者,如果您使用 Gradle,請新增
compile group: 'io.cucumber', name: 'cucumber-needle', version: '7.20.1'
目前尚無文件,但程式碼位於 GitHub 上。
當使用 DI 框架時,所有您的步驟定義、鉤子、轉換器等都將由框架的實例注入器建立。
當使用 DI 框架時,所有您的步驟定義、鉤子、轉換器等都將由框架的實例注入器建立。
Cucumber 的範例測試通常很小且沒有依賴性。然而,在現實生活中,測試通常需要存取應用程式特定的物件實例,這些實例也需要由注入器提供。這些實例需要提供給您的步驟定義,以便對它們執行操作並測試傳遞的結果。
使用 Cucumber 和 DI 框架的原因通常源於被測試的應用程式也使用相同的框架。因此,我們需要設定一個自訂注入器以用於 Cucumber。這個注入器將測試和應用程式實例連結在一起。
以下是一個使用 Google Guice 的典型步驟定義範例。使用 Cucumber 提供的 Guice 注入器將無法實例化所需的 appService
成員。
package com.example.app;
import static org.junit.Assert.assertTrue;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import io.cucumber.guice.ScenarioScoped;
import com.example.app.service.AppService;
import java.util.Objects;
import javax.inject.Inject;
@ScenarioScoped
public final class StepDefinition {
private final AppService appService;
@Inject
public StepDefinition( AppService appService ) {
this.appService = Objects.requireNonNull( appService, "appService must not be null" );
}
@When("the application services are started")
public void startServices() {
this.appService.startServices();
}
@Then("all application services should be running")
public void checkThatApplicationServicesAreRunning() {
assertTrue( this.appService.servicesAreRunning() );
}
}
AppService 的實作可能需要更多的參數和設定,通常必須由 Guice 模組提供。Guice 模組用於設定注入器,可能如下所示
package com.example.app.service.impl;
import com.example.app.service.AppService;
import com.google.inject.AbstractModule;
public final class ServiceModule extends AbstractModule {
@Override
protected void configure() {
bind( AppService.class ).to( AppServiceImpl.class );
// ... (further bindings)
}
}
然後實際的注入器會像這樣建立:injector = Guice.createInjector( new ServiceModule() );
這表示我們需要建立自己的注入器,並告訴 Cucumber 使用它。
Cucumber 的範例測試通常很小且沒有依賴性。然而,在現實生活中,測試通常需要存取應用程式特定的物件實例,這些實例也需要由注入器提供。這些實例需要提供給您的步驟定義,以便對它們執行操作並測試傳遞的結果。
使用 Cucumber 和 DI 框架的原因通常源於被測試的應用程式也使用相同的框架。因此,我們需要設定一個自訂注入器以用於 Cucumber。這個注入器將測試和應用程式實例連結在一起。
以下是一個使用 Google Guice 的典型步驟定義範例。使用 Cucumber 提供的 Guice 注入器將無法實例化所需的 appService
成員。
package com.example.app;
import static org.junit.Assert.assertTrue;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import io.cucumber.guice.ScenarioScoped;
import com.example.app.service.AppService;
import java.util.Objects;
import javax.inject.Inject;
@ScenarioScoped
public final class StepDefinition {
private final AppService appService;
@Inject
public StepDefinition( AppService appService ) {
this.appService = Objects.requireNonNull( appService, "appService must not be null" );
}
@When("the application services are started")
public void startServices() {
this.appService.startServices();
}
@Then("all application services should be running")
public void checkThatApplicationServicesAreRunning() {
assertTrue( this.appService.servicesAreRunning() );
}
}
AppService 的實作可能需要更多的參數和設定,通常必須由 Guice 模組提供。Guice 模組用於設定注入器,可能如下所示
package com.example.app.service.impl;
import com.example.app.service.AppService;
import com.google.inject.AbstractModule;
public final class ServiceModule extends AbstractModule {
@Override
protected void configure() {
bind( AppService.class ).to( AppServiceImpl.class );
// ... (further bindings)
}
}
然後實際的注入器會像這樣建立:injector = Guice.createInjector( new ServiceModule() );
這表示我們需要建立自己的注入器,並告訴 Cucumber 使用它。
每當 Cucumber 需要特定的物件時,它會使用物件工廠。Cucumber 有一個預設的物件工廠,它(在 Guice 的情況下)會建立一個預設的注入器,並將物件建立委派給該注入器。如果您想要自訂注入器,我們需要提供自己的物件工廠,並告訴 Cucumber 改用它。
package com.example.app;
import io.cucumber.core.backend.ObjectFactory;
import io.cucumber.guice.CucumberModules;
import io.cucumber.guice.ScenarioScope;
import com.example.app.service.impl.ServiceModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
public final class CustomObjectFactory implements ObjectFactory {
private Injector injector;
public CustomObjectFactory() {
// Create an injector with our service module
this.injector =
Guice.createInjector( Stage.PRODUCTION, CucumberModules.createScenarioModule(), new ServiceModule());
}
@Override
public boolean addClass( Class< ? > clazz ) {
return true;
}
@Override
public void start() {
this.injector.getInstance( ScenarioScope.class ).enterScope();
}
@Override
public void stop() {
this.injector.getInstance( ScenarioScope.class ).exitScope();
}
@Override
public < T > T getInstance( Class< T > clazz ) {
return this.injector.getInstance( clazz );
}
}
這是 Guice 的預設物件工廠,除了我們已將自己的綁定新增至注入器之外。Cucumber 會透過 java.util.ServiceLoader
載入物件工廠。為了讓 ServiceLoader 能夠選擇我們的自訂實作,我們需要提供檔案 META-INF/services/io.cucumber.core.backend.ObjectFactory
。
com.example.app.CustomObjectFactory
#
# ... additional custom object factories could be added here
#
現在我們必須告訴 Cucumber 使用我們的自訂物件工廠。有多種方式可以達成此目的。
每當 Cucumber 需要特定的物件時,它會使用物件工廠。Cucumber 有一個預設的物件工廠,它(在 Guice 的情況下)會建立一個預設的注入器,並將物件建立委派給該注入器。如果您想要自訂注入器,我們需要提供自己的物件工廠,並告訴 Cucumber 改用它。
package com.example.app;
import io.cucumber.core.backend.ObjectFactory;
import io.cucumber.guice.CucumberModules;
import io.cucumber.guice.ScenarioScope;
import com.example.app.service.impl.ServiceModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
public final class CustomObjectFactory implements ObjectFactory {
private Injector injector;
public CustomObjectFactory() {
// Create an injector with our service module
this.injector =
Guice.createInjector( Stage.PRODUCTION, CucumberModules.createScenarioModule(), new ServiceModule());
}
@Override
public boolean addClass( Class< ? > clazz ) {
return true;
}
@Override
public void start() {
this.injector.getInstance( ScenarioScope.class ).enterScope();
}
@Override
public void stop() {
this.injector.getInstance( ScenarioScope.class ).exitScope();
}
@Override
public < T > T getInstance( Class< T > clazz ) {
return this.injector.getInstance( clazz );
}
}
這是 Guice 的預設物件工廠,除了我們已將自己的綁定新增至注入器之外。Cucumber 會透過 java.util.ServiceLoader
載入物件工廠。為了讓 ServiceLoader 能夠選擇我們的自訂實作,我們需要提供檔案 META-INF/services/io.cucumber.core.backend.ObjectFactory
。
com.example.app.CustomObjectFactory
#
# ... additional custom object factories could be added here
#
現在我們必須告訴 Cucumber 使用我們的自訂物件工廠。有多種方式可以達成此目的。
當從命令列執行 Cucumber 時,可以將自訂物件工廠指定為引數。
java io.cucumber.core.cli.Main --object-factory com.example.app.CustomObjectFactory
當從命令列執行 Cucumber 時,可以將自訂物件工廠指定為引數。
java io.cucumber.core.cli.Main --object-factory com.example.app.CustomObjectFactory
如果存在,Cucumber 會使用屬性檔 (cucumber.properties
)。自訂物件工廠可以在此檔案中指定,並會在 Cucumber 執行時被選取。以下項目需要存在於 cucumber.properties
檔案中
cucumber.object-factory=com.example.app.CustomObjectFactory
如果存在,Cucumber 會使用屬性檔 (cucumber.properties
)。自訂物件工廠可以在此檔案中指定,並會在 Cucumber 執行時被選取。以下項目需要存在於 cucumber.properties
檔案中
cucumber.object-factory=com.example.app.CustomObjectFactory
適用於 JUnit 4 和 TestNG 的 Cucumber 模組允許透過 JUnit/TestNG 測試執行 Cucumber。可以使用 @CucumberOptions
註解設定自訂物件工廠。對於 JUnit 5,請參閱 cucumber-junit-platform-engine 文件。
適用於 JUnit 4 和 TestNG 的 Cucumber 模組允許透過 JUnit/TestNG 測試執行 Cucumber。可以使用 @CucumberOptions
註解設定自訂物件工廠。對於 JUnit 5,請參閱 cucumber-junit-platform-engine 文件。
Cucumber 在許多情況下會在事件匯流排上發出事件,例如:- 在剖析功能檔案期間 - 當執行測試情境時
Cucumber 在許多情況下會在事件匯流排上發出事件,例如:- 在剖析功能檔案期間 - 當執行測試情境時
每個事件都有一個 UUID 作為唯一識別碼。可以使用 cucumber.uuid-generator
屬性設定 UUID 產生器
| UUID 產生器 | 功能 | 效能 [每秒產生數百萬個 UUID] | 一般使用範例 | |——————————————————-|————————————————————————————————————————————————————————————————————|————————————|——————————————————————————————————————————————————————————————————————————————————————————–| | io.cucumber.core.eventbus.RandomUuidGenerator
|
io.cucumber.core.eventbus.IncrementingUuidGenerator
|實際專案的效能提升取決於功能的大小。
當未指定產生器時,會使用 RandomUuidGenerator
。
每個事件都有一個 UUID 作為唯一識別碼。可以使用 cucumber.uuid-generator
屬性設定 UUID 產生器
| UUID 產生器 | 功能 | 效能 [每秒產生數百萬個 UUID] | 一般使用範例 | |——————————————————-|————————————————————————————————————————————————————————————————————|————————————|——————————————————————————————————————————————————————————————————————————————————————————–| | io.cucumber.core.eventbus.RandomUuidGenerator
|
io.cucumber.core.eventbus.IncrementingUuidGenerator
|實際專案的效能提升取決於功能的大小。
當未指定產生器時,會使用 RandomUuidGenerator
。
當 RandomUuidGenerator
或 IncrementingUuidGenerator
都無法滿足專案需求時,可以定義自訂 UUID 產生器。這可以使用以下方法完成
java package mypackage.mysubpackage; import io.cucumber.core.eventbus.UuidGenerator; public class MyUuidGenerator implements UuidGenerator { @Override public UUID generateId() { return ... } }
META-INF/services/io.cucumber.code.eventbus.UuidGenerator
(例如,Maven resources
目錄) 將 UUID 產生器定義為 SPI,其中包含產生器類別名稱:java mypackage.mysubpackage.MyUuidGenerator
此 UUID 產生器將會覆寫預設的 RandomUuidGenerator
。
當 META-INF/services/...
檔案包含多個 UUID 產生器,或當類別路徑上有多個 META-INF/services/...
時,必須設定 cucumber.uuid-generator
屬性以選取所需的產生器。
當 RandomUuidGenerator
或 IncrementingUuidGenerator
都無法滿足專案需求時,可以定義自訂 UUID 產生器。這可以使用以下方法完成
java package mypackage.mysubpackage; import io.cucumber.core.eventbus.UuidGenerator; public class MyUuidGenerator implements UuidGenerator { @Override public UUID generateId() { return ... } }
META-INF/services/io.cucumber.code.eventbus.UuidGenerator
(例如,Maven resources
目錄) 將 UUID 產生器定義為 SPI,其中包含產生器類別名稱:java mypackage.mysubpackage.MyUuidGenerator
此 UUID 產生器將會覆寫預設的 RandomUuidGenerator
。
當 META-INF/services/...
檔案包含多個 UUID 產生器,或當類別路徑上有多個 META-INF/services/...
時,必須設定 cucumber.uuid-generator
屬性以選取所需的產生器。
有多個選項可以從您的資料庫移除狀態,以防止情境之間洩漏狀態。
建議在情境之間清除資料庫的方法是使用 Before
鉤子 在情境開始之前移除所有資料。這通常比使用 After
鉤子 更好,因為如果情境失敗,它允許您執行資料庫的事後檢查。
另一種方法是使用資料庫交易。
如果您的資料庫支援,您可以將交易包裝在每個情境周圍。
這可能會導致情境更快,但它會付出代價。您將無法執行事後檢查,並且將無法使用瀏覽器自動化。
若要使用此方法,您需要在 Before
鉤子中告訴 Cucumber 開始交易,然後在 After
鉤子中稍後將其回滾。
這是如此常見的事情,以至於多個 Cucumber 擴充功能提供了使用名為 @txn
的標籤的現成條件鉤子。
若要啟用它,您必須標記每個需要交易的 功能 或 情境 加上 @txn
@txn
Feature: Let's write a lot of stuff to the DB
Scenario: I clean up after myself
Given I write to the DB
Scenario: And so do I!
Given I write to the DB
請參閱 Cucumber-JVM 中的 spring-java-junit5 範例,以取得最簡設定。
請參閱 Cucumber-JVM 中的 spring-java-junit5 範例,以取得最簡設定。
如果您使用透過 HTTP 與您的應用程式對話的瀏覽器自動化工具,如果您的步驟定義和提供 HTTP 請求的 Web 應用程式各自都有自己的資料庫連線,則交易方法將不起作用。開啟交易後,交易永遠不會提交到資料庫 (但在每個情境結束時回滾)。因此,Web 伺服器的連線永遠不會看到來自 Cucumber 的資料,因此您的瀏覽器也不會看到。同樣地,Cucumber 的連線也看不到來自 Web 伺服器的資料。
在這種情況下,您必須關閉資料庫交易,並確保在每個情境之前明確刪除測試資料。
如果您使用 Ruby on Rails,您可以關閉功能或特定情境的交易。使用 @no-txn
標籤,如下所示
@no-txn
Feature: Lots of Scenarios with transactions off.
如果是這種情況,您應該使用暴力方法,其中資料會在每個情境之前明確刪除。或者這個
Feature: ...
@no-txn
Scenario: One Scenario with transactions off.
使用 Rails,您也可以在 features/support/env.rb
中全域關閉交易
Cucumber::Rails::World.use_transactional_fixtures = false
如果您使用 Ruby on Rails,一個處理此問題的好工具是 Ben Mabey 的 Database Cleaner gem,您可以使用 gem install database_cleaner
安裝。
您可以非常有效地將它與 @no-txn
標籤一起使用。例如,在例如 features/support/db_cleaner.rb
中的某處新增如下內容
require 'database_cleaner'
DatabaseCleaner.clean_with :truncation # clean once to ensure clean slate
DatabaseCleaner.strategy = :truncation
Before('@no-txn') do
DatabaseCleaner.start
end
After('@no-txn') do
DatabaseCleaner.clean
end
如果您沒有使用 Rails,您可以使用 Ruby 中的 DatabaseCleaner
使用以下程式碼重新建立整個 @no-txn
行為
# With this you should be able to tag the stories that need to use truncation.
# Otherwise, the transaction strategy will be used all the other times.
require 'database_cleaner'
DatabaseCleaner.clean_with :truncation # clean once to ensure clean slate
DatabaseCleaner.strategy = :transaction # use transactions by default
Before('@no-txn') do
DatabaseCleaner.strategy = :truncation
end
Before do
DatabaseCleaner.start
end
After do
DatabaseCleaner.clean
end
After('@no-txn') do
DatabaseCleaner.strategy = :transaction
end
您可以幫助我們改進此文件。 編輯此頁面。