beforeEach
λλ afterEach
κ° _μΈμ _ μ€νλλμ§μ λν λ¬Έμκ° μμ΅λλ€. λ΄ μ§κ°μ λ°λ₯΄λ©΄ νμ¬ μ»¨ν
μ€νΈμμ describe
/ it
λΈλ‘μ΄ μλ£λ λλ§λ€ before
/ after
μ€νν΄μΌ ν©λλ€.
κ·Έλ¬λ λ΄κ° μμμ°¨λ¦° λμμ beforeEach
λ° afterEach
κ° νμ¬ μ»¨ν
μ€νΈμμ before
/ after
_every_ it
λΈλ‘μΌλ‘ μ€νλλ€λ κ²μ
λλ€. λͺ¨λ μ€μ²© 컨ν
μ€νΈ.
λλ μ£Όλͺ©λλ λμμ΄ λ°μνκ³ μμμ 보μ¬μ£ΌκΈ° μν΄ κ°λ μ¦λͺ μ λ§λ€μμ΅λλ€. https://gist.github.com/twolfson/5883057#file -test-js
νΈμλ₯Ό μν΄ μ¬κΈ°μ μ€ν¬λ¦½νΈμ μΆλ ₯μ 볡μ¬/λΆμ¬λ£κΈ°νκ² μ΅λλ€.
describe('An afterEach hook', function () {
afterEach(function () {
console.log('afterEach run!');
});
before(function () {
console.log('before run!');
});
describe('in some nested contexts', function () {
before(function () {
console.log('nested before run!');
});
it('runs after this block', function () {
console.log('nested it run!');
});
it('runs again after this block', function () {
console.log('second nested it run!');
});
});
});
before run!
nested before run!
nested it run!
afterEach run!
second nested it run!
afterEach run!
λ΄κ° μ§κ΄μ μΌλ‘ μμνλ λμμ afterEach
λ€μμ ν λ² μ€νλλ second nested it
μ
λλ€.
before run!
nested before run!
nested it run!
second nested it run!
afterEach run!
μ§κ΄μ μΈ κΈ°λ₯μ μ¬μ© μ¬λ‘λ 컨ν
μ€νΈκ° μλ£λ ν this
컨ν
μ€νΈλ₯Ό μ 리νλ κ²μ
λλ€. νμ¬ κ΅¬νμ λͺ¨λ μ΄μ€μ
νμ 컨ν
μ€νΈλ₯Ό μ 리ν©λλ€.
afterEach(function () {
var key;
for (key in this) {
delete this[key];
}
});
describe('A banana', function () {
before(function () {
this.banana = new Banana();
});
describe('when peeled', function () {
before(function () {
this.peeledBanana = this.banana.peel();
});
it('is white', function () {
assert.strictEqual(this.peeledBanana.color, 'white');
// `afterEach` is invoked here, cleaning out `this`
});
it('is soft', function () {
// `this.peeledBanana` is no longer defined since `afterEach` cleaned it out
assert.strictEqual(this.peeledBanana.hardness, 'soft');
});
});
});
μ΄μ μ μ¬ν μλ ν μ€νΈ μ€μνΈμ κ°κ°μ μλ‘μ΄ μ»¨ν μ€νΈμμ λ°μ΄ν°λ² μ΄μ€ νΈλμμ μ μ¬λ κ²μ λλ€.
κ° μ€μ²© 컨ν
μ€νΈμμ after
λ₯Ό νΈμΆνμ¬ μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν μ μμ§λ§ νλ μμν¬μ νν¬κ° μμ μ μλ€κ³ μκ°ν©λλ€.
κΆκΈν λΆλ€μ μν΄ μ μ¬μ© μ¬λ‘μ λν ν΄κ²° λ°©λ²μ λ€μκ³Ό κ°μ΅λλ€.
// Before anything else is run
before(function () {
// Iterate over all of the test suites/contexts
this.test.parent.suites.forEach(function bindCleanup (suite) {
// Attach an afterAll listener that performs the cleanup
suite.afterAll(function cleanupContext () {
var key;
for (key in this) {
delete this[key];
}
});
});
});
+1
afterEach
λ λͺ¨λ Runnable
μΈμ€ν΄μ€ νμ μ€νλ©λλ€. κ·νμ κ²½μ° it()
λΈλ‘μ
λλ€. μ€μ²©λ λμμ μνμ§ μμΌλ©΄ ν
μ€νΈλ₯Ό μ€μ²©νμ§ λ§μμμ€. μ΄ λμμ λ³κ²½νλ κ²μ ν
μ΄λΈμ μμ΅λλ€.
λ λ²μ§Έ ν μ€νΈκ° 첫 λ²μ§Έ ν μ€νΈμμ μ μλ κ²μ μμ‘΄νλ€λ©΄ ν μ€νΈλ λλ½κ³ μλͺ»νκ³ μλ κ²μ λλ€. ν μ€νΈκ° μ€νλλ μμλ μ€μνμ§ μμ΅λλ€. κ·Έμ λ°λΌ ν μ€νΈλ₯Ό μμ±νλ©΄ λ κ°μΉκ° μμ κ²μ λλ€.
λν this
μκ°μ 90%μ μ무 κ²λ λ£μ νμκ° μμ΅λλ€.
describe('A banana', function () {
var banana;
before(function () {
banana = new Banana();
});
describe('when peeled', function () {
var peeledBanana;
beforeEach(function () {
// I'm assuming peel() has no side-effects since it returns a new object.
peeledBanana = banana.peel();
});
it('is white', function () {
assert.strictEqual(peeledBanana.color, 'white');
});
it('is soft', function () {
assert.strictEqual(peeledBanana.hardness, 'soft');
});
});
});
it() μμ€ λμ describe() μμ€μμ νν¬ λ©μλλ₯Ό μ€ννλ λ°©λ²μ΄ μμ΅λκΉ? μΌλΆ μλ리μ€μμ μ μ©ν μ μμ΅λλ€.
@RathaKM μ¬μ© μ¬λ‘λ 무μμ λκΉ?
μ΄κ²μ΄ μ’μ μμΈμ§ νμ€νμ§ μμ§λ§ λ€μμ΄ μ΄μ λν μ’μ μ¬μ© μ¬λ‘κ° λ κΉμ? @RathaKM μμ λ‘κ² μμ νμμμ€.
describe('A banana', function () {
var banana;
beforeEach(function () {
banana = new Banana();
});
describe('when peeled', function () {
var peeledBanana;
before(function () {
// Lets assume peel() HAS side-effects and doesn't return a new object.
banana.peel();
peeledBanana = banana;
});
it('is white', function () {
assert.strictEqual(peeledBanana.color, 'white');
});
it('is soft', function () {
assert.strictEqual(peeledBanana.hardness, 'soft');
});
});
describe('when set on FIRE', function () {
var flamingBanana;
before(function () {
// Same assumption as above
banana.setOnFire();
flamingBanana = banana
});
it('is hot', function () {
assert.isAbove(flamingBanana.temperature, 9000);
});
});
});
@cpoonolly : κ·νμ μ견μ κ°μ¬λ리며 λ€μ κ°μ Έμ€μΈμ. :) κ·νμ μλ λ Όλ¦¬μ μΌλ‘ μ€λͺ μμ€(BeforEach)μμ μλν κ²μΌλ‘ μμλλ κ²μ λλ€. κ·Έλ¬λ μ΄λ κ° μ€λͺ λ΄μμ 'fore()'λ₯Ό μ¬μ©νμ¬ λ¬μ±ν μ μμ΅λλ€.
λ΄κ° μ§λ©΄ ν λ¬Έμ λ μλ μμ λμ μμ΅λλ€.
var testData = [{country: 'NIL'}],
dataDriven = require('data-driven'),
assert = require('assert');
describe('@Testing_For_Describe_Level_Hook_Method_To_Update_TestData@', function () {
describe('<strong i="8">@Updated</strong> testData for US@', function () {
before(function (done) {
testData = [{country: 'US'}];
done();
});
dataDriven(testData, function () {
it('expecting updated testData for US', function (ctx, done) {
assert.equal(ctx.country, 'US');
done();
});
});
});
describe('<strong i="9">@Updated</strong> testData for UK@', function () {
before(function (done) {
testData = [{country: 'UK'}];
done();
});
dataDriven(testData, function () {
it('expecting updated testData for UK', function (ctx, done) {
assert.equal(ctx.country, 'UK');
done();
});
});
});
});
μ¬κΈ°μ ν μ€νΈ μ€μνΈλ μ€ν¨ν©λλ€. '_it_' λΈλ‘ λ°λ‘ μ μ νΈμΆλ 'before()' νν¬ λ©μλ λ΄μμ _testData_λ₯Ό μ λ°μ΄νΈν©λλ€. κ·Έλ¬λ μ°λ¦¬λ '_it_' λΈλ‘μ μ€ννκΈ° μ μ μ€νλ _dataDriven()_ λ΄μ _testData_ λ³μλ₯Ό μ¬μ©ν©λλ€.
λ°λΌμ μ¬κΈ°μ νμν κ²μ _'it'_ λΈλ‘ μ€νμ΄ μμλκΈ° μ μ λ³μλ₯Ό μ λ°μ΄νΈν μ₯μμ λλ€. 'describe' λΈλ‘(λ 벨 νν¬ λ©μλ μ€λͺ ) μ§μ μ _before()_ νν¬ λ©μλ μ€νμ΄ νμν μ μμ΅λλ€.
μ΄μ λ¬Έμ κ° λͺ νν΄μ§κΈ°λ₯Ό λ°λλλ€.
μ΄μ λν μΆκ° λ Όμκ° μμμ΅λκΉ?
μ μ΄λ° κ²μ μ»μ μ μμ΅λκΉ?
describe('Create Article', () => {
beforeEach(() => console.log('CLEAN DB'))
context('When Article is valid', () => {
before(() => console.log("INSERTING VALID ARTICLE"))
it('should not fail')
it('should have some properties')
it('should send an email')
})
context('When Article is not valid', () => {
before(() => console.log("INSERTING NOT VALID ARTICLE"))
it('should fail')
it('should not send an email')
})
})
context
λΈλ‘ μ μ DB it
λΈλ‘ μ μ μλλ¦¬μ€ μ€μ μ΄κ²μ ν©λ²μ μΈ μ¬μ© μ¬λ‘κ° μλλκΉ?
@marqu3z κ·νμ μ¬μ© μ¬λ‘λ₯Ό λ°λ₯΄λ €κ³ ν©λλ€. ν©λ²μ μ λλ€. λ¬Έμ λ λ€μκ³Ό κ°μ΅λλ€. before νν¬κ° beforeEach νν¬λ³΄λ€ λ¨Όμ μ€νλ©λκΉ? νμ§λ§ beforeEach νν¬ λ€μμ μ€ννλ €λ©΄ before νν¬κ° νμν©λκΉ?
(μ λ§λ‘ λͺ¨λ ν μ€νΈ μΌμ΄μ€μ λν΄ DBλ₯Ό μ 리νμκ² μ΅λκΉ? 첫 λ²μ§Έ ν μ€νΈ μΌμ΄μ€λ§ μ±κ³΅νκ³ λλ¨Έμ§λ λ°μ΄ν°κ° μλ κ²μ²λΌ 보μ λλ€. νμ§λ§ λͺ¨λ ν μ€νΈ μΌμ΄μ€μ λν΄ DBλ₯Ό μ 리νκ³ μΆλ€κ³ κ°μ νκ² μ΅λλ€.)
λ€μμ Mochaκ° μλ κ·Έλλ‘ μ¬μ© μ¬λ‘λ₯Ό ν΄κ²°νκΈ° μν λ κ°μ§ μλμ λλ€.
(1) beforeEachλ₯Ό μ¬μ©νμ§λ§ λΆμΈμ λ€μ§μΌλ―λ‘ beforeEachλ ν λ²λ§ μ€νλ©λλ€.
describe('Create Article', () => {
beforeEach(() => console.log('CLEAN DB'))
context('When Article is valid', () => {
let flip = true;
beforeEach(() => flip && (flip = false; console.log('INSERTING VALID ARTICLE')))
it('should not fail')
it('should have some properties')
it('should send an email')
})
context('When Article is not valid', () => {
let flip = true;
beforeEach(() => flip && (flip = false; console.log('INSERTING NOT VALID ARTICLE')))
it('should fail')
it('should not send an email')
})
})
(2) μ΄κ²μ νλ λ€λ₯Έ λ°©λ² - μ΄κ²μ λ³λ‘ μ’μ§ μμ΅λλ€!
describe('Create Article', () => {
let cleanDB = function(fn){
return function(done){
actuallyCleanDB(function(err){
if(err) return done(err);
fn(done);
});
}
};
context('When Article is valid', () => {
before(() => console.log('INSERTING VALID ARTICLE'))
it('should not fail', cleanDB(function(done){})
it('should have some properties', cleanDB(function(done){}))
it('should send an email', cleanDB(function(done){}))
})
context('When Article is not valid', () => {
before(() => console.log('INSERTING NOT VALID ARTICLE')))
it('should fail', cleanDB(function(done){}))
it('should not send an email',cleanDB(function(done){}))
})
})
κ·νμ λ¬Έμ λ₯Ό μ΄ν΄νκ³ μλμ§ μλ €μ£Όμλ©΄ ν΄κ²° λ°©λ²μ μκ°νλ λ° λ λ§μ μκ°μ ν μ νκ² μ΅λλ€. μ μ루μ μ€ μ΄λ κ²λ κ·Έλ€μ§ μ’μ§λ μμ§λ§ κ·νμ λ¬Έμ λ₯Ό μ΄ν΄νκ³ μλμ§ νμΈνκ³ μΆμ΅λλ€.
@RathaKM
it() ν
μ€νΈ μΌμ΄μ€λ₯Ό λΉλκΈ°μμΌλ‘ λ±λ‘νκ³ μμ΅λκΉ? κ·Έλ λ€λ©΄ νμ©λμ§ μμ΅λλ€. describe/after/afterEach/before/beforeEach
λͺ¨λ λκΈ°μμΌλ‘ λ±λ‘ν΄μΌ ν©λλ€.
// event loop tick X
dataDriven(testData, function () {
// it() must be called in the same event loop tick as X above
it('expecting updated testData for UK', function (ctx, done) {
assert.equal(ctx.country, 'UK');
done();
});
});
λν ctxλ μ΄λμμ μ€λκ°? μ΅μ Mocha κΈ°λ₯μ λν μ΅μ μ λ³΄κ° μλ μλ μμ§λ§ λ³Έ μ μ΄ μμ΅λλ€.
it(foo, function(ctx, done){
// where is ctx coming from?
});
λλ @marqu3zκ° μ€λͺ
ν κ²κ³Ό λκ°μ μλ리μ€μ μμ΅λλ€. describe
μμ€ beforeEach
μ λν μ§μμ λ°κ³ μΆμ΅λλ€.
μ΄ μΌλ°μ μΈ μλ리μ€λ₯Ό κ°μ§ λͺ¨λ μ¬λμκ² νμ¬ λΈλ‘μ λͺ¨λ μ νκ΅°μ λ°λ³΅νκ³ κ°κ°μ beforeAll
νν¬λ₯Ό μΆκ°νλ μ΄ λμ°λ―Έ ν¨μλ₯Ό λ§λ€μμ΅λλ€.
function beforeEachSuite (fn) {
before(function () {
let suites = this.test.parent.suites || []
suites.forEach(s => {
s.beforeAll(fn)
let hook = s._beforeAll.pop()
s._beforeAll.unshift(hook)
})
})
}
μ΄κ²μ λ΄κ° κ±°μ 1λ μ μ μ€λͺ ν μ¬μ© μ¬λ‘λ₯Ό μ κΈ ν΄μ ν©λλ€.
describe('Create Article', () => {
beforeEachSuite(() => console.log('CLEAN DB'))
context('When Article is valid', () => {
before(() => console.log("INSERTING VALID ARTICLE"))
it('should not fail')
it('should have some properties')
it('should send an email')
})
context('When Article is not valid', () => {
before(() => console.log("INSERTING NOT VALID ARTICLE"))
it('should fail')
it('should not send an email')
})
})
μ΄ μ¬μ© μ¬λ‘κ° μ μ©νμ§ μκ±°λ ν©λ²μ μ΄μ§ μμ μ΄μ λ₯Ό μ¬μ ν μ΄ν΄νμ§ λͺ»ν©λλ€.
μ΄ μ루μ
μ beforeEachSuite
λ° afterEachSuite
μ λν PRλ‘ μ νλ μ μμ΅λλ€.
μ, μ ν¬κ° μ΄κ²μ νμλ‘ ν©λλ€.
https://github.com/mochajs/mocha/issues/911#issuecomment -316736991κ³Ό κ°μ λ§μ μ¬μ© μ¬λ‘κ° μμ΅λλ€.
+1
+1
λλ λ°©κΈ λΉμ·ν κ²μ μ°Ύκ³ μλμ΄ μ€λ λλ₯Ό μ°μ°ν λ°κ²¬νμ΅λλ€. κ·Έλμ μ΄ κΈμ 보μλ λ€λ₯Έ λΆλ€κ»...
@marqu3z κ° μ체 NPM ν¨ν€μ§ mocha-suite-hooks
λν΄ μ€λͺ
ν μ κ·Ό λ°©μμ μ μ©νμ΅λλ€.
λ°λΌμ before
κ° μΆ©λΆνμ§ μκ³ beforeEach
κ° λ무 λ§μ μν©μ μ²ν κ²½μ° beforeSuite
λ₯Ό μλν΄ λ³΄μμμ€.
ν¨ν€μ§λ μμ§ μμ μνμ΄λ―λ‘ νΌλλ°±μ΄ μμΌλ©΄ λλ¨ν κ°μ¬νκ² μ΅λλ€!
κ°μ₯ μ μ©ν λκΈ
μ΄ μΌλ°μ μΈ μλ리μ€λ₯Ό κ°μ§ λͺ¨λ μ¬λμκ² νμ¬ λΈλ‘μ λͺ¨λ μ νκ΅°μ λ°λ³΅νκ³ κ°κ°μ
beforeAll
νν¬λ₯Ό μΆκ°νλ μ΄ λμ°λ―Έ ν¨μλ₯Ό λ§λ€μμ΅λλ€.μ΄κ²μ λ΄κ° κ±°μ 1λ μ μ μ€λͺ ν μ¬μ© μ¬λ‘λ₯Ό μ κΈ ν΄μ ν©λλ€.
μ΄ μ¬μ© μ¬λ‘κ° μ μ©νμ§ μκ±°λ ν©λ²μ μ΄μ§ μμ μ΄μ λ₯Ό μ¬μ ν μ΄ν΄νμ§ λͺ»ν©λλ€.
μ΄ μ루μ μ
beforeEachSuite
λ°afterEachSuite
μ λν PRλ‘ μ νλ μ μμ΅λλ€.