<!-- 译者:Github@wizardforcel -->
# 编写 spec #
我们已经通过一些例子查看并编写了一些spec,现在是更进一步查看spec框架本身的时候了。确切地说,你在Atom中如何编写测试呢?
Atom使用[Jasmine](http://jasmine.github.io/1.3/introduction.html)作为spec框架。任何新的功能都要拥有specs来防止回归。
## 创建新的 spec ##
[Atom的spec](https://github.com/atom/atom/tree/master/spec)和[包的spec](https://github.com/atom/markdown-preview/tree/master/spec)都要添加到它们各自的`spec`目录中。下面的例子为Atom核心创建了一个spec。
### 创建spec文件 ###
spec文件必须以`-spec`结尾,所以把`sample-spec.coffee`添加到`atom/spec`中。
### 添加一个或多个`describe`方法 ###
`describe`方法有两个参数,一个描述和一个函数。以`when`开始的描述通常会解释一个行为;而以方法名称开头的描述更像一个单元测试。
```
describe "when a test is written", ->
# contents
```
或者
```
describe "Editor::moveUp", ->
# contents
```
### 添加一个或多个`it`方法 ###
`it`方法也有两个参数,一个描述和一个函数。尝试去让`it`方法长于描述。例如,`this should work`的描述并不如`it this should work`便于阅读。但是`should work`的描述要好于`it should work`。
```
describe "when a test is written", ->
it "has some expectations that should pass", ->
# Expectations
```
### 添加一个或多个预期 ###
了解预期(expectation)的最好方法是阅读[Jasmine的文档](http://jasmine.github.io/1.3/introduction.html#section-Expectations)。下面是个简单的例子。
```
describe "when a test is written", ->
it "has some expectations that should pass", ->
expect("apples").toEqual("apples")
expect("oranges").not.toEqual("apples")
```
## 异步的spec ##
编写异步的spec刚开始会需要些技巧。下面是一些例子。
### Promise ###
在Atom中处理Promise更加简单。你可以使用我们的`waitsForPromise`函数。
```
describe "when we open a file", ->
it "should be opened in an editor", ->
waitsForPromise ->
atom.workspace.open('c.coffee').then (editor) ->
expect(editor.getPath()).toContain 'c.coffee'
```
这个方法可以在`describe`、`it`、`beforeEach`和`afterEach`中使用。
```
describe "when we open a file", ->
beforeEach ->
waitsForPromise ->
atom.workspace.open 'c.coffee'
it "should be opened in an editor", ->
expect(atom.workspace.getActiveTextEditor().getPath()).toContain 'c.coffee'
```
如果你需要等待多个promise,对每个promise使用一个新的`waitsForPromise`函数。(注意:如果不用`beforeEach`这个例子会失败)
```
describe "waiting for the packages to load", ->
beforeEach ->
waitsForPromise ->
atom.workspace.open('sample.js')
waitsForPromise ->
atom.packages.activatePackage('tabs')
waitsForPromise ->
atom.packages.activatePackage('tree-view')
it 'should have waited long enough', ->
expect(atom.packages.isPackageActive('tabs')).toBe true
expect(atom.packages.isPackageActive('tree-view')).toBe true
```
### 带有回调的异步函数 ###
异步函数的Spec可以`waitsFor`和`runs`函数来完成。例如:
```
describe "fs.readdir(path, cb)", ->
it "is async", ->
spy = jasmine.createSpy('fs.readdirSpy')
fs.readdir('/tmp/example', spy)
waitsFor ->
spy.callCount > 0
runs ->
exp = [null, ['example.coffee']]
expect(spy.mostRecentCall.args).toEqual exp
expect(spy).toHaveBeenCalledWith(null, ['example.coffee'])
```
访问[Jasmine文档](http://jasmine.github.io/1.3/introduction.html#section-Asynchronous_Support))来了解更多关于异步测试的细节。
## 运行 spec ##
大多数情况你会想要通过触发`window:run-package-specs`来运行spec。这个命令不仅仅运行包的spec,还运行了Atom的核心spec。它会运行当前项目spec目录中的所有spec。如果你想要运行Atom的核心spec和所有默认包的spec,触发`window:run-all-specs`命令。
要想运行spec的一个有限的子集,使用`fdescribe`和`fit`方法。你可以使用它们来聚焦于单个或者几个spec。在上面的例子中,像这样聚焦于一个独立的spec:
```
describe "when a test is written", ->
fit "has some expectations that should pass", ->
expect("apples").toEqual("apples")
expect("oranges").not.toEqual("apples")
```
### 在CI中运行 ###
在CI环境,类似Travis和AppVeyor中运行spec现在非常容易。详见文章“[Travis CI For Your Packages](http://blog.atom.io/2014/04/25/ci-for-your-packages.html)”和“[AppVeyor CI For Your Packages](http://blog.atom.io/2014/07/28/windows-ci-for-your-packages.html)”。