μλ νμΈμ, λ¨κ³ μΈμμ λν΄ μνλλ μ격ν κ²μ¬μ κ°μΉλ₯Ό μ΄ν΄νμ§λ§ μ΄ μ»¨νΈλ‘€μ μ¬μ©μμκ² λ€μ μ λ¬ν νμκ° μλ€κ³ μκ°ν©λλ€.
μλ₯Ό λ€μ΄, μ κ²½μ°μλ λ¨κ³ νΈμΆ μ νμ μΌλΆ μΌλ° μ²λ¦¬ λ Όλ¦¬λ₯Ό μΆκ°νλ €λ λ¨κ³ ꡬν κΈ°λ₯ μ£Όμμ μΌλ° λνΌ κΈ°λ₯μ ꡬννλ €κ³ ν©λλ€. μ΄ μΌλ° λνΌμ κ²½μ° μ λ¬λ λͺ¨λ μΈμμ μ‘μΈμ€ν΄μΌ νλ―λ‘ λͺ μμ 맀κ°λ³μλ₯Ό μ μΈνλ λμ μΈμ λ°°μ΄μ μ‘μΈμ€ν΄μΌ ν©λλ€. νμ¬ μ€μ΄λ 맀κ°λ³μλ₯Ό μ격νκ² κ²μ¬νκΈ° λλ¬Έμ μ΄ μμ μ μννμ§ λͺ»νκ² ν©λλ€.
μ€μ νμ§ μμΌλ©΄ falseλ‘ κ°μ£Όλλ skipStrictParameterCheckμ κ°μ μ΅μ κ°μ²΄μ λ€λ₯Έ κ΅¬μ± λ§€κ°λ³μλ₯Ό μΆκ°νλ κ²μ μ μνκ³ μΆμ΅λλ€. κ·Έλ κ² νλ©΄ κ°μ₯ μΌλ°μ μΌλ‘ μ¬μ©λλ κΈ°λ³Έ λμμ μ격ν κ²μ¬κ° λμ§λ§ νλ μμν¬λ₯Ό μ¬μ©νμ¬ νλ μμν¬λ₯Ό μ€μ¬μΌλ‘ λ λ§μ κ²μ ꡬμΆνλ €λ λ€λ₯Έ μ¬μ©μμκ²λ JavaScriptμ λμ κΈ°λ₯ μ€ μΌλΆλ₯Ό νμ©ν μ μλ μ μ°μ±μ μ 곡ν©λλ€.
κ°μ μμ²μ νμ΅λλ€. #445λ₯Ό μ°Έμ‘°νμΈμ. :)
@riaan53 , μ, λλ κ·Έκ²μ 보μκ³ λΆννλ μλ§λ μ¬λ°λ₯Έ μ΄μ λλ¬Έμ μμ²μ΄ κ±°λΆλμμ΅λλ€. λλ κ·Έ μΆλ‘ μ λμνμ§ μμ§λ§, λ ν° νλ μμν¬ κ΅¬μΆμ μΌλΆλ‘ μ΄ κΈ°λ₯μ μ¬μ©μκ° κ·Έκ²μ λ¨μ©νμ§ μλ ν μ€μνλ€κ³ μκ°ν©λλ€. λ°λΌμ μ΄κ²μ μ격νκ² μ νμ μΈ κ΅¬μ±μΌλ‘ λ§λλ κ²μ΄ μ’μ΅λλ€.
λΉμ μ΄ λ§νλ μ΄ μΌλ° μ²λ¦¬ λ Όλ¦¬λ 무μμ λκΉ?
νμ νλ. ν κ°μ§ μ¬μ© μ¬λ‘μμλ λͺ¨λ κ°λ°μκ° λ¨κ³ μ μμμ ννμ μ°Έμ‘°λ₯Ό μ¬μ©ν μ μκΈ°λ₯Ό λ°λλλ€. μ: '${admin} μ¬μ©μκ° μμ€ν μ λ‘κ·ΈμΈν λ'.
μ΄μ μ΄ κ²½μ° ${admin}μ JSON νμΌμμ ν΄κ²°λ μ μμΌλ©° ν΄κ²°μ λν μ± μμ λ¨κ³ μ μλ₯Ό ꡬννλ λμ κ°λ°μμκ² μμ΅λλ€. κ·Έλ° μ’ λ₯μ μμ± νμΈμ μ€μ λ‘ λ³΄λ©΄ κ°λ°μκ° μ ν μΈμνμ§ λͺ»νλ μΌλ° μ½λλ‘ μνν μ μμ΅λλ€.
μ΄λ₯Ό νμ©νκΈ° μν΄ Cucumberκ° μ£Όμ ν μμ μΈμλ₯Ό μλ½νκ³ ν΄κ²°ν λ€μ ν΄κ²°λ κ°μ μ€μ λ¨κ³ ꡬνμ μ£Όμ νλ κ°λ°μ λ¨κ³ ꡬν μ£Όμμ μΌλ° ν¨μ λνΌλ₯Ό μ½κ² λ§λ€ μ μμ΅λλ€.
νμ¬ Cucumberμ μ ν¨μ± κ²μ¬λ₯Ό ν΅ν΄ ν¨μμ μ¬λ°λ₯Έ μμ λ§€κ° λ³μκ° μλμ§ νμΈνλ κ²κ³Ό κ°μ μΌλ° ν¨μλ₯Ό μμ±ν μ μμ΅λλ€. μ κ²½μ°μλ μΌλ° λνΌ ν¨μκ° λͺ λͺ λ μΈμλ₯Ό νμ©νμ§ μκ³ 'μΈμ' κ°μ²΄μ λλ€.
λ΄κ° μ΄ν΄ν μ μκΈ°λ₯Ό λ°λλλ€. νμ¬ νλ‘μ νΈμλ λ¨κ³ ꡬνμ λν μΌλ° λνΌ κΈ°λ₯μ΄ νμν λ€λ₯Έ μ¬μ© μ¬λ‘λ μμ΅λλ€.
λ¨κ³ μΈμ λ³νμ ꡬννλ©΄ λ¬Έμ κ° ν΄κ²°λ©λλ€. https://github.com/cucumber/cucumber/wiki/Step-Argument-Transforms?
μ μ, μ μ¬μ μΌλ‘ μ°Έμ‘° ν΄μλ λ¬Έμ λ₯Ό ν΄κ²°ν μ μμ΅λλ€. κ·Έλ¬λ λ€λ₯Έ μ΄μ λ‘ λ¨κ³ ꡬν μ£Όμμ μΌλ° λνΌ ν¨μλ₯Ό ββμΆκ°ν΄μΌ ν©λλ€.
μλ₯Ό λ€μ΄ ν κ°μ§ μ΄μ λ νλ μμν¬λ‘ Cucumberμ ν¨κ» Protractorλ₯Ό μ¬μ©νκ³ Protractorμμ WebDriver μ μ΄ νλ¦μ μ¬μ©μ μ§μ μ½μμ λ±λ‘ν΄μΌ λ€μ λ¨κ³λ‘ μ§ννκΈ° μ μ μ΄λ¬ν μ¬μ©μ μ§μ μ½μμ΄ ν΄κ²°λ λκΉμ§ λΆμ§λ°ν κΈ°λ€λ €μΌ νλ€λ κ²μ λλ€.
Cucumberλ Promiseκ° ν΄κ²°λ λκΉμ§ κΈ°λ€λ¦¬μ§λ§(λ¨κ³ ꡬνμμ λ°νλ κ²½μ°) λΆλͺ ν WebDriverλ₯Ό μΈμνμ§ μμΌλ©° λ°νλ Promiseλ₯Ό WebDriverμ λ±λ‘νκΈ° μν΄ κ° λ¨κ³ ꡬνμ μΆκ° μ½λλ₯Ό μΆκ°ν΄μΌ νλ κ²½μ°κ° κ°μ₯ λ§μ΅λλ€.
μ΄κ²μ 맀κ°λ³μ κ²μ¬κ° Cucumberμ μν΄ μνλμ΄μΌ νλ μΌλ° ν¨μ λνΌλ₯Ό ν΅ν΄ ν΄κ²°νκΈ° λ§€μ° μ¬μ΄ λ¬Έμ μ λλ€.
λλ μ§κΈμ΄ λ¬Έμ μ λ λ² λΆλͺμ³€λ€.
κ°μ₯ λμ λλ κ²μ Then
λ¨κ³λ§λ€ retry
λμ°λ―Έλ₯Ό ꡬννλ κ²μ
λλ€.
cucumber.Then = function(match, callback) {
const retryingCallback = (...args) => retry(async () => await callback(...args));
cucumber.Then(match, retryingCallback);
};
λλ μ΄ λμ°λ―Έλ₯Ό μ¬μ©νμ¬ κΆκ·Ήμ μΌλ‘ μΌκ΄λ λ°±μλμμ νμ΄λ° λ¬Έμ λ₯Ό μ²λ¦¬ν©λλ€. κΈ°λ³Έμ μΌλ‘ yμ΄κ° μ§λκ±°λ μ½λ°±μ΄ μ§λκ° λκΉμ§ xμ΄λ§λ€ μ½λ°±μ μ€νν©λλ€.
μνκΉκ²λ μ΄λ‘ μΈν΄
function has 0 arguments, should have 1 (if synchronous or returning a promise) or 2 (if accepting a callback)
λ΄κ° μ§κΈ μ¬μ©νκ³ μλ λμμ λͺ¨λ Then
λ¨κ³μμ λμ°λ―Έλ₯Ό νΈμΆνλ κ²μ΄λ―λ‘ λ§μ μ½λ μ€λ³΅μ΄ λ°μν©λλ€.
this.Then(/^I see that "([^"]*)" does not have a destination$/, async clientName => {
return retry(async () => {
const client = await homeView.clientByName(clientName);
expect(client.destinationName).to.not.exist;
});
});
λ λ€λ₯Έ κ²½μ°λ λ‘κ·ΈμΈμ μν λμ°λ―Έ κΈ°λ₯μ μνλ λ κ°λ¨ν κ²½μ°μ λλ€.
function loggedIn(username, func) {
return (...args) => {
await accounts.login(username);
return func(...args)
};
}
this.Then(/^someone logged in as "([^"]*)" sees a destination named "([^"]*)"$/, loggedIn(assert.destinationExists));
λν μ΄κ²μ λ§μ μ½λ μ€λ³΅μ μ μ₯ν©λλ€.
λ§μ§λ§μΌλ‘ λͺ¨λ μΉμΈ ν
μ€νΈλ₯Ό μ€ννμ§λ§ λͺ¨λ Then
μ½λ°± μ μ μλ²λ₯Ό λ€μ μμνλ μ νκ΅°μ μΆκ°νκ³ μΆμ λκ° μμ κ²μΌλ‘ μμν©λλ€(μλ² λ€μ μμμΌλ‘ μΈν΄ λ¬Έμ κ° λ°μνμ§ μλλ‘ νκΈ° μν΄). λ€μ λ§νμ§λ§, λ§μ μ€λ³΅.
PS μ¬μλ λμ°λ―Έ:
const patience = 250;
const interval = 5;
function delay(time) {
return new Promise(function (fulfill) {
setTimeout(fulfill, time);
});
}
async function attempt(start, func) {
const attemptDate = new Date();
try {
return await func();
} catch (errr) {
const timeElapsed = attemptDate.getTime() - start.getTime();
if (timeElapsed < patience) {
await delay(interval);
return await attempt(start, func);
} else {
throw errr;
}
}
}
export async function retry(func) {
const start = new Date();
return await attempt(start, func);
}
_νΈμ§νλ€_
λ΄ λ°©λ²μ ν΄νΉνλ €κ³ νμ΅λλ€.
function splat(func) {
return (one, two, three, four, five, six, seven, eight, nine, ten) => {
if (typeof ten !== 'undefined') {
return func(one, two, three, four, five, six, seven, eight, nine, ten);
} else if (typeof nine !== 'undefined') {
return func(one, two, three, four, five, six, seven, eight, nine);
} else if (typeof eight !== 'undefined') {
return func(one, two, three, four, five, six, seven, eight);
} else if (typeof seven !== 'undefined') {
return func(one, two, three, four, five, six, seven);
} else if (typeof six !== 'undefined') {
return func(one, two, three, four, five, six);
} else if (typeof five !== 'undefined') {
return func(one, two, three, four, five);
} else if (typeof four !== 'undefined') {
return func(one, two, three, four);
} else if (typeof three !== 'undefined') {
return func(one, two, three);
} else if (typeof two !== 'undefined') {
return func(one, two);
} else if (typeof one !== 'undefined') {
return func(one);
} else {
return func();
}
};
}
cucumber.Then = function(match, callback) {
const retryingCallback = splat((...args) => retry(async () => await callback(...args)));
cucumber.Then(match, retryingCallback);
};
νμ§λ§
function has 10 arguments, should have 1 (if synchronous or returning a promise) or 2 (if accepting a callback)
λλ₯Ό μ¬ν ν¬λλ‘ λ§λ€μ΄
λ€μ μ κΈΈμ΄λ₯Ό μ μ§νκΈ° μν΄ ν¨μλ₯Ό λννλ μμ λλ€. μ΄ μμ μ μννλ μμ λ Έλ λͺ¨λλ§ μμΌλ©΄ μ’μ κ²μ λλ€.
μ μ κ°μ¬ν©λλ€! λ¨κ³ μ μλΉ μΈμ μλ₯Ό μ§μ νλ©΄ μλν©λλ€. λ§μ£ ?
μλ₯Ό λ€μ΄
this.Then(/^someone logged in as "([^"]*)" sees a destination named "([^"]*)"$/, createProxy(loggedIn(assert.destinationExists), 2));
λμκ² κ°μ₯ μκΈν λ¬Έμ λ μ¬λ¬ λ¨κ³ μ μμ λν μΌλ° λ―Έλ€μ¨μ΄λ₯Ό μΆκ°ν μ μλ€λ κ²μ
λλ€. createProxy
μ κ°μ κ²μ λ―Έλ€μ¨μ΄ λ±λ‘μ νμ©νλ κ°μ²΄λ‘ λ§λ λ€μ λͺ¨λ λ¨μΌ λ¨κ³ μ μμμ μΈμ μλ₯Ό μλ €μ£Όλ©΄ μλν μ μμ΅λλ€. (μ 첫 λ²μ§Έ μλ₯Ό μμΈν μ΄ν΄λ³΄λ©΄ retry
ν¨μκ° μ΄λ₯Ό λννκΈ° λλ¬Έμ createProxy
μ§μ μ¬μ©ν μ μμμ μ μ μμ΅λλ€. κ·Έ λ°λκ° λμ΄μΌ νμ§λ§ createProxy
λ κ° μ½λ°±μ λν μΈμμ μλ₯Ό μ μ μμ΅λλ€)
κ·Έλλ μ€λ₯λ₯Ό λ μ μλ κ²κ³Ό λΉκ΅νλ©΄ μ¬μ ν μ΄μν©λλ€. :μκ²°ν:
proxyLength
λ₯Ό μ λ¬νλ λμ λννκ³ function.length
μ¬μ©νλ ν¨μμ λ³νμ μ¬μ©ν μ μλ€κ³ μκ°ν©λλ€.
μ’μ μ μ, κ°μ¬ν©λλ€!
λλ λ€μκ³Ό κ°μ κ²μ μ»μλ€.
cucumber.Then = function(match, callback) {
cucumber.Then(match, retryProxy(callback));
};
function retryProxy(func) {
const numberOfArgs = func.length;
switch (numberOfArgs) {
case 0: return () => retry(func);
case 1: return (a) => retry(func, a);
case 2: return (a, b) => retry(func, a, b);
case 3: return (a, b, c) => retry(func, a, b, c);
case 4: return (a, b, c, d) => retry(func, a, b, c, d);
case 5: return (a, b, c, d, e) => retry(func, a, b, c, d, e);
}
}
ν΄κ²°λμ§ μλ λ κ°μ§λ λ‘κ·ΈμΈ λμ°λ―Έμ κ²½μ°μ κΈ°λ³Έ 맀κ°λ³μλ₯Ό νμ©νλ κ²μ΄μ§λ§ μ΄ λ κ°μ§λ₯Ό ν΄κ²°ν μ μμ΅λλ€.
μ΄μ λ¨κ³ μ μλ₯Ό μ‘°μ νμ§ μκ³ λ―Έλ€μ¨μ΄λ₯Ό μΆκ°ν μ μμ΄ κΈ°μ©λλ€!
@thomasvanlankveld μλ€μνΌ, νΉμ ν¨μ κΈΈμ΄λ₯Ό μ 곡νκΈ° μν΄ ν¨μλ₯Ό λννλ μ΄ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ°Ύμμ΅λλ€: https://github.com/blakeembrey/arity
@susil-rxr μλ ν¨μ κΈΈμ΄λ₯Ό μ μ§νκΈ° μν΄ μΌλ° ν¨μ λνΌμμμ κ°μ΄ ν μ μμ΅λκΉ?
2.0.0-rc.1
μ΄μ μΌλ° ν¨μ λνΌλ₯Ό μΆκ°ν μ μμ΅λλ€. λν μλ κΈ°λ₯ κΈΈμ΄λ₯Ό μ μ§νλ κΈ°λ₯μ΄ λ΄μ₯λμ΄ μμ΅λλ€.
μ΄ μ€λ λλ λ«ν ν μ΅κ·Ό νλμ΄ μμκΈ° λλ¬Έμ μλμΌλ‘ μ κ²Όμ΅λλ€. κ΄λ ¨ λ²κ·Έμ λν μ λ¬Έμ λ₯Ό μ¬μμμ€.