Rails测试简介

Many developers will rely on interacting with an app to prove it works the way they want. But this is not the most efficient way to do things. Writing tests for your code is a good practice, and it can save time finding bugs down the line. In this series of blog posts, I’m going to talk about how to write tests for a Rails application.

许多开发人员将依赖与应用程序进行交互以证明其能够按所需方式工作。 但这不是做事的最有效方法。 为您的代码编写测试是一种很好的做法,它可以节省寻找错误的时间。 在这一系列博客文章中,我将讨论如何为Rails应用程序编写测试。

First, I’ll talk a bit about why testing is so important. Writing tests is useful because you can use them to check that a small piece of your code works the way it was intended. This is also a good way to become more familiar with your code, because it forces you to thinks about what exactly you want each piece of your code to do. And when you find a bug in your code you can have a better idea of where it is, because you know for sure that certain things work. Also, once you’ve written a test, you can run it over and over to check that everything still works as expected, even after you have made a major change to your app.

首先,我将谈谈为什么测试如此重要。 编写测试非常有用,因为您可以使用它们来检查一小段代码是否按预期的方式工作。 这也是使您更加熟悉代码的好方法,因为它迫使您考虑要让您的代码的每一部分真正执行的操作。 而且,当您在代码中找到错误时,您可以更好地了解错误的位置,因为您肯定知道某些事情可以正常工作。 另外,编写测试后,即使对应用程序进行了重大更改,也可以一次又一次地运行它以检查一切是否仍按预期进行。

Writing tests in Rails is relatively easy. A Rails application started with rails new already has a testing framework set up for you, in a folder called test. It has a file structure like this:

在Rails中编写测试相对容易。 以rails new开头的Rails应用程序已经在一个名为test的文件夹中为您设置了测试框架。 它 具有这样的文件结构:

- test
- channels/
- controllers/
- fixtures/
- helpers/
- integration/
- mailers/
- models/
- system/
- application_system_test_case.rb
- test_helper.rb

Each of the folders in test are designed to test a specific part of your application, and I’ll go into each of them in a later blog post. For this one, I’ll just focus on the basics of writing and running tests.

测试中的每个文件夹都旨在测试应用程序的特定部分,我将在以后的博客文章中介绍每个文件夹。 对于这一部分,我将只关注编写和运行测试的基础知识。

As an example, I’ll make references to files in a project created with these commands:

例如,我将引用使用以下命令创建的项目中的文件:

~ // ♥ > rails g scaffold Author name age:integer
~ // ♥ > rails g scaffold Book title author_id:integer

When you use a rails generator like rails g scaffold or rails g resource to create files for your models, rails will automatically create some test files for these models that you can fill in. In the models folder I have a file like this:

当您使用rails生成器(例如rails g scaffoldrails g resource为模型创建文件时,rails会自动为这些模型创建一些测试文件以供您填充。在models文件夹中,我有一个类似这样的文件:

# author_test.rbrequire 'test_helper'class AuthorTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

The class AuthorTest inherits from ActiveSupport::TestCase which gives us a number of useful methods, including the one used in the example commented out here. The test method takes a test name(here, the name is “the truth”) and a block(everything between the do and end), and if you give it a descriptive name, it can be very clear what the test is designed to look for.

AuthorTest类继承自ActiveSupport :: TestCase ,它为我们提供了许多有用的方法,包括在此处注释的示例中使用的方法。 测试方法采用一个测试名称(此处为“the truth” )和一个块( doend之间的所有内容),如果给它一个描述性名称,则可以很清楚地了解测试的目的寻找。

In the do…end block is an assertion. Assertions are designed to evaluate something for expected results. There are a variety of available assertions, and there is a full list of them here. Each test can have as many assertions as you want, and the test will only pass if all the assertions are successful. An example assertion for my Authors/Books project test that an author will not save without a name. A test to check for this could look like this:

do…end块中是一个断言。 断言旨在评估某些东西是否达到预期结果。 有多种可用的断言,并有他们的完整列表在这里 。 每个测试可以具有任意数量的断言,并且仅当所有断言均成功时,测试才会通过。 我的“作者/书籍”项目测试的一个示例断言是,没有名称,作者将不会保存。 对此进行检查的测试可能如下所示:

test "author should not save without name" do
author = Author.new
assert_not author.save
end

Now that we have a test written, we need to be able to run it and see the results. There are a variety of ways to run your tests; you could run all of them at once with rails test, but this isn’t very efficient. Running all of your tests can take longer, so if you just want to check the results of a specific test, the best way is to drill down to run just the tests in the file, or even the test on a given line. So the command to run the test I wrote would look like this (7 being the line the test starts on):

现在我们已经编写了一个测试,我们需要能够运行它并查看结果。 有多种方法可以运行您的测试。 您可以使用rails test一次运行所有它们,但这不是很有效。 运行所有测试可能需要更长的时间,因此,如果您只想检查特定测试的结果,最好的方法是向下钻取以仅运行文件中的测试,甚至运行给定行中的测试。 因此,运行我编写的测试的命令应如下所示(7是测试开始的行):

~ // ♥ > rails test test/models/author_test.rb:7

But, because I never wrote the validation to require an author to have a name into my Author model class, the test fails, and it denotes the failure with an F:

但是,因为我从未编写过验证来要求作者Author模型类中有一个名字,所以测试失败,并且用F表示失败:

# Running:FFailure:
AuthorTest#test_author_should_not_save_without_name
[/path/rails-testing/test/models/author_test.rb:17]:
Expected true to be nil or falserails test test/models/author_test.rb:7Finished in 1.116573s, 0.8956 runs/s, 0.8956 assertions/s.
1 runs, 1 assertions, 1 failures, 0 errors, 0 skips

Unfortunately, this failure isn’t very descriptive about what exactly went wrong. That’s because I didn’t give the assertion a massage to output so it used the default, “Expected true to be nil or false”. To make the test clearer I can add a message, and I’ll also add another assertion to check that an author cannot be saved with an age that is not positive:

不幸的是,这种失败并不能完全说明发生了什么问题。 那是因为我没有给断言发送消息,所以它使用默认值“ Expected true to nil or false” 。 为了使测试更清晰,我可以添加一条消息,并且还要添加另一个声明,以检查是否可以保存作者的年龄不是正数:

test "should not save if validations fail" do
author = Author.new
assert_not author.save, "saved the author without a name" author = Author.new(name: "J. K. Rowling", age: -10)
assert_not author.save, "saved the author with a non-positive age"
end

Then I’ll add the validations to the model file like so:

然后,将验证添加到模型文件中,如下所示:

#author.rbclass Author < ApplicationRecord
has_many :books validates :name, presence: true
validates :age,
end

Running the test now gives me a passing result:

现在运行测试给我通过的结果:

# Running:.Finished in 0.267856s, 3.7333 runs/s, 7.4667 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips

There is one more result you can get from running a test, and that is an error. The same as in any other code, errors can occur from spelling mistakes or references to variables that don’t exist. For example, if I had misspelled assert_not as asset_not the result would look like this, with an E to designate the error:

通过运行测试可以获得更多结果,这是一个错误。 与任何其他代码相同,由于拼写错误或对不存在的变量的引用而可能导致错误。 例如,如果我将assert_not拼写错误为asset_not则结果将如下所示,并带有E来指定错误:

# Running:EError:
AuthorTest#test_should_not_save_if_validations_fail:
NoMethodError: undefined method `asset_not' for
#<AuthorTest:0x00007fea2ffdd178>
test/models/author_test.rb:12:in `block in <class:AuthorTest>'rails test test/models/author_test.rb:7Finished in 0.766280s, 1.3050 runs/s, 1.3050 assertions/s.
1 runs, 1 assertions, 0 failures, 1 errors, 0 skips

The error helpfully points to the line where it occurred, on line 12 in author_test.rb. It also ran the first assertion before it found the error in the second one and stopped.

该错误有助于指出发生错误的行,即author_test.rb中的第12 。 它还在发现第二个错误并停止之前运行了第一个声明。

And this is most of what you need to know about the basics of testing in rails. In summary, you write tests in blocks that use assertions to verify the results you expect. Then you run the tests and, if you are clear in your test massages, the results give helpful information about any tests that didn’t pass. In my next blog post I’ll go into the types of tests to write in each of the directories that Rails gives you in the test folder.

这是您需要了解的有关Rails测试基础知识的大部分内容。 总而言之,您将在使用断言来验证所需结果的块中编写测试。 然后,您可以运行测试,并且如果您对测试内容有所了解,那么结果将提供有关未通过的任何测试的有用信息。 在我的下一篇博客文章中,我将介绍在Rails在测试文件夹中为您提供的每个目录中编写的测试类型

翻译自: https://medium.com/swlh/intro-to-testing-with-rails-2698467b893c

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值