我的摩卡测试单独工作,但一次运行时失败
Posted
技术标签:
【中文标题】我的摩卡测试单独工作,但一次运行时失败【英文标题】:My mocha tests work separately, but fail when run all at once 【发布时间】:2012-12-16 07:38:33 【问题描述】:这可能与异步代码有关,但我不确定是什么。当我将它们分开运行时,两者都通过了:mocha test/models.coffee
和 mocha test/login.coffee
但是当我与npm test
一起运行测试时,describe 'saving another user with same username', ->
失败了。我想数据库在运行该步骤时会被清除,因此它会保存而不是产生错误,因为它应该是一个唯一值。
另外:我对这个软件测试的东西非常陌生,如果有人有任何提示,或者想批评我的公然错误,请随时给我发电子邮件(查看我的个人资料)
谢谢!!
这是我的两个测试文件(coffeescript):
/test/models.coffee
should = require 'should'
User = require '../models'
# function to find our test user, John Egbert
findJohn = (cb) ->
User.findOne 'public.username': 'john', (err, john) ->
throw err if err
cb(john)
before (done) ->
# Drop all users from database
User.collection.drop()
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: username: 'john', done
describe 'create user', ->
it 'should create a document that can be found', (done) ->
findJohn (user) ->
should.exist user
done()
describe 'user password', ->
it 'should NOT be stored in plaintext', (done) ->
findJohn (user) ->
user.password.should.not.eql 'test123'
done()
it 'should return true for matching password', (done) ->
findJohn (user) ->
user.comparePassword 'test123', (err, isMatch) ->
isMatch.should.eql true
done()
it 'should return false for non-matching password', (done) ->
findJohn (user) ->
user.comparePassword 'wrong_password', (err, isMatch) ->
isMatch.should.not.eql true
done()
describe 'saving another user with same username', ->
it 'should produce an error', (done) ->
User.create public: username: 'john', (err) ->
should.exist err
done()
/test/login.coffee
:
should = require 'should'
User = require '../models'
login = require '../services/login'
before (done) ->
# Drop all users from database
User.collection.drop()
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: username: 'john', done
describe 'login', ->
it 'should return true for an existing username/password combo', (done) ->
login username: 'john', password: 'test123', (err, loggedIn) ->
should.not.exist(err)
loggedIn.should.be.true
done()
it 'should return false for a bad username/password combo', (done) ->
login username: 'john', password: 'wrong_pass', (err, loggedIn) ->
should.not.exist(err)
loggedIn.should.be.false
done()
还有/models.coffee
fs = require 'fs'
path = require 'path'
mongoose = require 'mongoose'
#Connect to mongodb
#TODO: env variable to choose production/development/testing databases
mongoose.connect 'localhost', 'siglr'
models =
for file in fs.readdirSync './schemas'
if path.extname(file) is '.coffee'
modelName = path.basename file, '.coffee'
schema = require "./schemas/#modelName"
models[modelName] = mongoose.model modelName, schema
# key is model name, value is actual mongoose model
module.exports = models
【问题讨论】:
【参考方案1】:这里有一件事情可能会创造出让你发疯的比赛条件。删除用户集合时,您没有传递回调。我不能确定这是否会导致问题,例如在删除集合之前插入测试用户,但是这种未能正确使用回调来等待异步操作完成的模式是您的程序的秘诀以难以调试的方式行为不端。试试这个:
before (done) ->
# Drop all users from database
User.collection.drop (err) ->
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: username: 'john', done
第二个建议:将console.log
语句放在每个describe/before/it
的开头(第一个语句)和另一个紧接在调用done()
之前的语句,看看它们是否按照您期望的顺序出现。
【讨论】:
仍然有同样的问题,不过是个好建议。我应该学习如何使用异步库来做类似的事情嗯? 好的,我删除了我之前的评论,因为我过于热心。我编辑了我的问题并添加了models.coffee
,这可能是我的问题所在。我有一种感觉,我尝试创建一个可以加载模型的对象并没有按预期工作,并且在我的两个测试需要时创建了 2 个单独的模型实例。我可能只是重构模型加载代码,直到它工作......明天!
我发现由于某种原因,当使用npm test
运行时,我在public.username
上丢失了我的索引......所以我用适当的值调用User.collection.ensureIndex()
User.create
s 在前面的步骤中,它可以工作。【参考方案2】:
我发现在与npm test
一起运行测试时,由于某种原因,public.username
索引被删除。但是在单独运行每个测试时保持不变。
我在test/models.coffee
中更改了以下内容:
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: username: 'john', done
致以下:
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: username: 'john', ->
User.collection.ensureIndex 'public.username': 1 , unique: true , (err) ->
throw err if err
done()
...调用ensureIndex 一个内部猫鼬函数,该函数称为when the model is compiled initially,但由于某种原因在测试的生命周期中被删除。
使用猫鼬 3.5.4
【讨论】:
原因很可能是彼得提到的,集合被丢弃而没有管理它的回调。删除一个集合会完全删除它,索引,数据,所有这些。下次插入文档时,mongo 会再次自动创建一个集合,但索引将不再存在,因为它将是一个全新的集合。管理您的回调并考虑从集合中删除所有文档而不是删除。 谢谢,使用User.find().remove
的好建议以上是关于我的摩卡测试单独工作,但一次运行时失败的主要内容,如果未能解决你的问题,请参考以下文章
当所有测试一起运行时,Android Instrumented 测试失败