2014-10-30 1 views
3

여기 casperjs 및 mocha로 해결하려고하는 문제가 있습니다. 페이지의 요소의 텍스트 값을 테스트하여 5 ~ 10 초 동안 업데이트되는지 확인하려고합니다. 아이디어는 내가 값을 잡고, 배열로 밀어 넣고, 배열이 20 개의 항목을 가질 때까지 500ms를 기다린 다음 반복합니다. 약 10 초가 걸립니다. 그런 다음 배열에 밑줄/로다시의 _.uniq 함수를 실행하고 배열 길이가 > 1인지 테스트합니다.CasperJS 테스트를 실행할 때 모카가 시간 초과 또는 콜백을 수행하지 않음

내가 겪고있는 문제는 테스트를 말하는 것이 성공/실패이기 때문에 모카가 완료되기를 기다리지 않는다는 것입니다. 나는 모카의 타임 아웃을 늘릴 수 있다고 생각했지만, 이것은 아무런 차이를 만들지 못했습니다. 아래 코드를 참조하십시오. 나는 가독성을 위해 주석 처리했다. 500ms로 설정 간격 값과

it('has elements whose values update', function() { 
    // 20 seconds, which should be plenty of time 
    this.timeout(20000); 

    casper.then(function() { 
     // The test array 
    var values = [], 
     // So we can stop the intervals 
     intervalId; 

    function getValue() { 
     // Grab element's text value 
     var value = casper.evaluate(function() { return $('#element').text(); }); 

     // Push in to our test array 
     values.push(value); 

     // 20 * 500ms == 10 seconds or 10000ms 
     // When set to 500ms, this block never runs. The test passes before it has a chance to 
     if (values.length === 20) { 

     // Stop it from checking the value any further 
     clearInterval(intervalId); 

     // Test to see we've had more than one unique value in the 10 seconds 
     expect(_.uniq(values).length).to.be.gt(1); 
     } 
    } 

    // Wait for the value on the page to populate 
    // It defaults to '-' when the page loads 
    casper.waitFor(function() { 
     return this.evaluate(function() { 
     return $('#element').text() !== '-'; 
     }); 

    // Start the check with a delay of 500ms between each check 
    }, function then() { 
     intervalId = setInterval(getValue, 500); 
    }); 
    }); 
}); 

난 다음 테스트 모카 이동 전에 values 2-3 요소 값을 얻는다. odder가 심지어 내가 console.log(values) 모카 후 화면에 인쇄되면 테스트가 통과 된 것으로 판단됩니다. 그 이유는 values.length이 절대로 10이되지 않으므로 expect 호출이 호출되지 않기 때문입니다. 테스트는 통과하는 것으로 가정합니다. 다음은 500ms 간격의 테스트 출력입니다.

Dashboard 
✓ has elements whose values update (202ms) 
Values: ["20,832,022"] 
Values: ["20,832,022","20,832,372"] 
Values: ["20,832,022","20,832,372","20,832,722"] 

✓ has the page title of leads (41ms) 

2 passing (11s) 

20 개의 항목이 없어도 통과합니다. 그것은 어딘가에 시간 초과로 인해 절대로 확인하지 않습니다. 여기에 50ms 간격의 출력이 있습니다 :

Dashboard 

✓ has elements whose values update (341ms) 
Values: ["20,400,667"] 
Values: ["20,400,667","20,400,718"] 
Values: ["20,400,667","20,400,718","20,400,718"] 
Values: ["20,400,667","20,400,718","20,400,718","20,400,769"] 
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769"] 
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820"] 
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820"] 
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820","20,400,871"] 
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820","20,400,871","20,400,871"] 
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820","20,400,871","20,400,871","20,400,922"] 
Final Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820","20,400,871","20,400,871","20,400,922"] 

✓ has the page title of leads (41ms) 

2 passing (8s) 

나는 50ms로 더 많은 것을 얻었지만 테스트는 0.5 초에 불과합니다. 이 값을 업데이트하는 데 페이지의 다른 값 중 일부는 실행 가능하지 않습니다.

콜백을 it 문으로 전달하려고했지만 모카가이를 무시하고 호출되기를 기다리지 않습니다.

도구의 제한 사항입니까? 아니면 잘못 사용하고 있습니까?

아래의 방법으로 완료 콜백을 사용해 보았습니다.

it('has elements whose values update', function (done) { 

expect(_.uniq(values).length).to.be.gt(1); 
done(); 

그것은 아직도 내가 비동기로 테스트를 표시 한 것을 무시합니다. 500ms에서 여전히 if 문이나 done 호출에 도달하지 않고 통과합니다. 50ms에서이 오류가 발생합니다 :

done() called multiple times 

나는 mocha-casperjs을 사용하고 있습니다. 이것이 영향을 미칠 수 있습니까?

답변

2

mocha-casperjs는 기본값 done을 사용하지 않는 것으로 보입니다. CasperJS의 제어 흐름을 사용하기 때문에 테스트 단계가 완료되었음을 알 수 있습니다. 귀하의 경우에는 setInterval을 통해 getValue을 호출하여 제어 흐름을 중단합니다.

그것은 더 나은 것은 다음과 같이 getValue에 재귀 호출을 사용하는 코드를 리팩토링 :

function getValue() { 
    // Grab element's text value 
    var value = this.evaluate(function() { return $('#element').text(); }); 

    // Push in to our test array 
    values.push(value); 

    // 20 * 500ms == 10 seconds or 10000ms 
    // When set to 500ms, this block never runs. The test passes before it has a chance to 
    if (values.length === 20) { 
    // Test to see we've had more than one unique value in the 10 seconds 
    expect(_.uniq(values).length).to.be.gt(1); 
    } else { 
    this.wait(500, getValue); 
    } 
} 

// Wait for the value on the page to populate 
// It defaults to '-' when the page loads 
casper.waitFor(function() { 
    return this.evaluate(function() { 
    return $('#element').text() !== '-'; 
    }); 

// Start the check with a delay of 500ms between each check 
}, function then() { 
    this.wait(500, getValue); 
}); 

getValue 캐스퍼 단계 있습니다.

많은 리팩토링이없는 또 다른 해결 방법은 깨진 제어 흐름의 측면을 따라 두 번째 실행을시키는 것입니다. 세미 - 글로벌 변수 someGlobalVariable이 필요합니다. 어쩌면 intervalId을이 용도로 사용할 수 있지만 상단에 someGlobalVariable = false;을 사용하는 것이 좋습니다.

intervalId = setInterval(getValue, 500); 
this.waitFor(function check(){ 
    return someGlobalVariable; 
}, function then(){ 
    // do something else 
}, null, 20000); 

하고

expect(_.uniq(values).length).to.be.gt(1); 
someGlobalVariable = true; 
으로 멈추게