看起来Exunit为设置块https://hexdocs.pm/ex_unit/ExUnit.Callbacks.html提供了回调。我很好奇如何使用小袋鼠功能测试。在测试集成测试时,我基本上是在每个场景中创建用户。我基本上想要提取样板代码并将其用于我编写的每个测试。这是我目前的集成测试设置。
test "a user can create a location", %{session: session} do
assert session
|> visit("/users")
|> click_link("Create new account")
|> fill_in("Name", with: "Billy Joel")
|> fill_in("Email", with: "billy@example.com")
|> fill_in("Password", with: "password")
|> click_on("Create new user")
|> click_link("New Project")
|> fill_in("Name", with: "Senior Class Air Quality")
|> click_on("Submit")
|> click_link("Senior Class Air Quality")
|> click_link("New Location")
|> click_on("Submit")
|> find(".alert-danger p")
|> text == "Oops, something went wrong! Please check the errors below."
assert session
|> fill_in("Name", with: "A new location")
|> select("Type", option: "office")
|> click_on("Submit")
|> find(".alert-info")
|> text == "Location created successfully."
assert session
|> find("td", count: 3)
|> List.first
|> text == "A new location"
end
test "a user can edit a location", %{session: session} do
project = Factory.project()
Factory.location(%{project_id: project.id})
assert session
|> visit("/users")
|> click_link("Create new account")
|> fill_in("Name", with: "Billy Joel")
|> fill_in("Email", with: "billy@example.com")
|> fill_in("Password", with: "password")
|> click_on("Create new user")
|> click_link("New Project")
|> fill_in("Name", with: "Senior Class Air Quality")
|> click_on("Submit")
|> click_link("Senior Class Air Quality")
|> click_link("New Location")
|> fill_in("Name", with: "A new location")
|> select("Type", option: "office")
|> click_on("Submit")
|> click_link("Edit location")
|> fill_in("Name", with: "different name")
|> select("Type", option: "home")
|> click_on("Submit")
|> find(".alert-info")
|> text == "Location updated successfully."
那里有很多重复。如何使用设置块来合并部分代码?
答案 0 :(得分:1)
setup
和setup_all
函数为模块中的所有测试运行完全相同的设置代码,如果您需要为所有测试执行完全相同的设置,它们是最有用的。这方面的一个例子是设置应用程序所依赖的模拟服务。
在您的情况下,您似乎有一些相同的步骤,但是当您添加更多测试时,并不一定会为所有测试添加常见设置。但是,您可以将测试组成的各个概念步骤重构为一个单独的模块,您将在所有集成测试中使用该模块:
defmodule TestHelpers do
# wallaby imports here
def create_user(session, name, email, password) do
session
|> visit("/users")
|> click_link("Create new account")
|> fill_in("Name", with: name)
|> fill_in("Email", with: email)
|> fill_in("Password", with: password)
|> click_on("Create new user")
end
def create_project(session, name) do
session
|> click_link("New Project")
|> fill_in("Name", with: name)
|> click_on("Submit")
end
def create_location(session, type), do: _modify_location("New Location", session, type, name)
def edit_location(session, type), do: _modify_location("Edit location", session, type, name)
defp _modify_location(link_text, session, location_type, location_name) do
session = session
|> click_link(link_text)
session = case location_name do
nil -> session
x when is_binary(x) -> fill_in(session, "Name", with: location_name)
end
session = case location_type do
nil -> session
x when is_binary(x) -> select(session, "Type", option: location_type)
end
session
|> click_on("Submit")
end
end
现在测试只包含TestHelpers
中定义的助手和断言:
defmodule Test do
import TestHelpers
@project_name "Senior Class Air Quality"
# aliases, uses, imports here
test "a user can create a location", %{session: session} do
session = session
|> create_user("Billy Joel", "billy@example.com", "password")
|> create_project(@project_name)
|> click_link(@project_name)
|> create_location(nil, nil)
assert session
|> find(".alert-danger p")
|> text == "Oops, something went wrong! Please check the errors below."
session = session
|> create_location("A new location", "office")
assert session
|> find(".alert-info")
|> text == "Location created successfully."
assert session
|> find("td", count: 3)
|> List.first
|> text == "A new location"
end
test "a user can edit a location", %{session: session} do
project = Factory.project()
Factory.location(%{project_id: project.id})
session = session
|> create_user("Billy Joel", "billy@example.com", "password")
|> create_project(@project_name)
|> click_link(@project_name)
|> create_location("office", "A new location")
|> modify_location("home", "different_name")
assert session
|> find(".alert-info")
|> text == "Location updated successfully."
end
end
您也可以类似地提取警报消息断言,将它们转换为单行,这应该使每个测试都具有可读性和健壮性,例如,如果链接文本或div
类发生更改 - 您只会帮助改变帮助。
当然,如果你发现自己在测试中有重复的多步骤设置,你可以将它作为辅助函数直接使用它:
def standard_setup(session) do
session
|> create_user("Billy Joel", "billy@example.com", "password"
|> create_project(@project_name)
|> click_link(@project_name)
|> create_location("office", "A new location")
end