<!-- 譯者: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)”。