现有项目已在生产中部署.我们想在它上面添加一些测试(越快越好),我必须选择BDD方式(rspec/cucumber)或TDD方式(TestUnit).我真的从BDD开始,我想知道什么是最好的决定?我很害怕在现有的rails项目上使用rspec/cucumber(本周部署并需要非常快速的迭代)将很难做到(特别是它不应该以这种方式使用,我的意思是我们应该首先编写故事/特征并从那里迭代).
TestUnit可能更合理.
你有什么想法吗?分享经验?一些建议?
我的测试全部通过,我的结果如下所示:
入门
完成时间为361.988408秒.
479个测试,1017个断言,0个失败,0个错误,0个挂起,0个遗漏,0个通知0%通过
为什么我没有看到我曾经在rails 2.3中看到的常见进度点?为什么说"0%通过"?我想知道在看似空白的地方,这些点是否变成了白色并且实际上是在那里?我不想改变我的终端有黑色背景.;-)
同样在我的单元测试中,它说"在0.0秒内完成".这显然是错的.
我正在使用testunit 2.4.0为rails 3.1 app编写控制器测试.
我想断言某个标题没有出现在页面上.
我正在使用这样的assert_select:
assert_select 'h1', {:text => /Key Dates/, :count => 0}
Run Code Online (Sandbox Code Playgroud)
并收到以下错误:
ArgumentError: assertion message must be String or Proc: <</Key Dates/>
expected but was <"Planner Maternity leave">.>(<Test::Unit::Assertions::AssertionMessage>)
Run Code Online (Sandbox Code Playgroud)
我已经跟踪了这个事实,即创建一个实例并将其传递给测试单元的assert_select调用.但是在testunit 2.2版(2011年2月)中添加了检查,检查传入的消息的类型.这些检查触发了上面看到的.build_messageAssertionMessageassertArgumentError
我不确定错误在于测试单元是否过度严格或者assert_select是否传递了错误的对象类型.
你能建议如何最好地跟进吗?任何解决方法?
假设在所有测试中执行setup或者teardown相同的操作可能是昂贵的操作,并且在测试运行期间其结果不会被弄乱.在每次测试之前/之后让它们运行似乎是不对的.
那么有没有一种首选的方法只在第一次测试执行之前运行设置/拆卸代码,并且只在最后一次测试运行之后?
编辑:我正在处理的特定情况应该测试Net :: FTP的一些扩展,从而建立一个FTP连接并设置一些远程对象进行测试:
class TestFTPExtensions < Test::Unit::TestCase
def setup
# Setup connection
@ftp = Net::FTP.new 'localhost', 'anonymous'
@ftp.passive = true
# Create remote test directory
@ftp.mkdir 'dir'
# Create remote test file
path = File.join Dir.tmpdir, 'file'
File.open path, 'w' do |f|
@ftp.put f
end
File.delete path
end
def teardown
@ftp.rmdir 'dir'
@ftp.delete 'file'
@ftp.close
end
# imagine some tests here that don't change/remove any remote objects
end
Run Code Online (Sandbox Code Playgroud) 我正在使用Capybara测试使用HTML5本地存储在客户端上保留数据值的应用程序的前端部分。为了确保来自一个测试的会话数据不会干扰另一个测试,我确保调用每个测试Capybara.reset_sessions!的teardown方法。
我很快意识到该方法实际上并不会清除本地存储,建议您确保window.localStorage.clear()在每次测试后手动执行该teardown方法,因此我将这行代码放入测试类的方法中,如下所示:
def teardown
super
page.execute_script("localStorage.clear()")
end
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试运行它时:
1) Error:
CartTest#test_adding_an_item_to_cart:
Selenium::WebDriver::Error::NoScriptResultError: <unknown>: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.
(Session info: chrome=34.0.1847.116)
(Driver info: chromedriver=2.8.240825,platform=Linux 3.8.0-29-generic x86_64)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,相反,我尝试将JavaScript调用移至测试的结尾,如下所示:
test "test with storage" do
# Test some browser stuff
page.execute_script("localStorage.clear()")
end
Run Code Online (Sandbox Code Playgroud)
工作正常。现在,我当然可以在每项测试的末尾添加该行,以使其正常运行,但是那会很混乱。有人知道如何使其在tearndown方法中起作用吗?
我有一个路由,我正在使用约束来检查主机,然后是一个基本相同但没有主机限制的路由(这些实际上是命名空间,但为了简单起见,这个例子将会这样做):
match "/(:page_key)" => "namespace_one/pages#show", :constraints => proc {|env| env['SERVER_NAME'] == 'test.mysite.local' }
match "/(:page_key)" => "namespace_two/pages#show"
Run Code Online (Sandbox Code Playgroud)
当通过浏览器访问时以及在定义主机和执行get "/page_key"等时的集成测试中,这些工作完全符合预期.
但是我想编写确保这些路由到目前为止工作的测试我没有太多运气,因为下面的测试(目前ActionController::IntegrationTest我可以设置主机)匹配没有约束的测试:
assert_routing '', { :controller => 'namespace_one/pages', :action => 'show' }
=> The recognized options <{"action"=>"show", "controller"=>"frontend/pages"}>
did not match <{"action"=>"show", "controller"=>"namespace_two/pages"}>,
difference: <{"controller"=>"namespace_one/pages"}>
Run Code Online (Sandbox Code Playgroud)
如果我尝试在限制proc中转储env,我得到的就是--- :controller.
如果我摆脱assert_routing只是做一个get :show调用并转储@controller它确实解析到正确的控制器(正如预期的那样,这些路由都可以通过HTTP请求正常工作).
我在让Capybara使用Rails时遇到了问题.只测试那个有趣的测试用品.好的,在附加的代码中有几个等价的测试.第一个是使用Rails附带的shoulda-context + Test :: Unit.第二次测试也是用水豚和上下文进行的.
require 'integration_test_helper'
class UsersTest < ActionDispatch::IntegrationTest
fixtures :all
context "signup" do
context "failure" do
setup do
@attr = { :name => "", :email => "", :password => "", :password_confirmation => "" }
end
should "not make a new user" do
assert_no_difference 'User.count' do
post_via_redirect "users", :user =>@attr # enviem les dades d'un nou usuari via create (POST /users)
assert_template 'users/new' # ens retorna a users/new, que significa que no s'ha creat l'usuari
assert_select "div#error_explanation" # …Run Code Online (Sandbox Code Playgroud) 我试图在我的Rails应用程序中使用Capybara和Cucumber.所以,这就是我所做的:
Gemfilerails generate capybara:install --cucumber这是我的功能(是的,我正在创建博客应用程序):
Feature: Browse posts
So that I can browse through the posts
As a visitor
I want to see all and/or particular posts
Scenario: Viewing all the posts
Given Posts exist
When I navigate to the website home
Then I should see all the posts
Scenario: Viewing particular post
Given Post #1 exists
When I navigate to /posts/view/1
Then I should see the post with id=1
Run Code Online (Sandbox Code Playgroud)
这是步骤定义:
Given /^Posts exist$/ do …Run Code Online (Sandbox Code Playgroud) 这是我的rakefile中唯一的东西.
Rake::TestTask.new do |t|
t.libs << "test"
t.test_files = FileList['test/test*.rb']
t.verbose = true
end
Run Code Online (Sandbox Code Playgroud)
当我运行rake时,我得到的输出是
uninitialized constant Rake::TestTask
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我希望我的rake文件运行我指定的所有单元测试.任何输入都会有所帮助.谢谢
在 Rails 项目中创建单元测试时,我问自己的第一个问题是“组织单元测试的约定是什么”,因为几乎所有其他内容都是由约定决定的。另外,我很好奇 MiniTest、TestUnit 和 Rspec 之间的约定是否发生变化。
到目前为止,我所做的是将 Rails 目录结构镜像到 test/unit 目录中,如下所示:
[Rails Root]
/lib/
./postgres.rb
./awesome_parser.rb
/app/helpers
./psychic_helper.rb
/test/unit/
./lib/postgres.rb
./lib/awesome_parser.rb
./app/helpers/psychic_helper
Run Code Online (Sandbox Code Playgroud)
组织测试的最传统方式是什么,这样当其他人加入这个项目时他们就不会咒骂我的名字?
testunit ×10
ruby ×4
capybara ×3
unit-testing ×3
bdd ×1
cucumber ×1
installation ×1
javascript ×1
rake ×1
routing ×1
rspec ×1
ruby-1.9.2 ×1
shoulda ×1
tdd ×1
teardown ×1