코드를 변경하거나 추가한 후에는 기존 단위 테스트를 실행하고 도움이 됩니다. 모든 테스트는 압축되지 않은 버전의 코드에서 실행됩니다.
단위 테스트에는 JS 테스트와 블록 생성기 테스트, 이렇게 두 가지가 있습니다.
JS 테스트
JS 테스트는 Blockly의 핵심입니다. Mocha를 사용하여 단위 테스트를 실행합니다. Sinon으로 종속 항목 스텁 Chai: 코드에 관한 어설션을 만듭니다.
테스트 실행
블록 및 블록 샘플 모두에서 npm run test
는 단위 테스트를 실행합니다. Blockly에서는 린팅 및 컴파일과 같은 다른 테스트도 실행합니다. 다음과 같은 작업을 할 수 있습니다.
브라우저에서 tests/mocha/index.html
도 열어 모든 Mocha를 대화형으로 실행합니다.
있습니다
테스트 작성
Mocha TDD 인터페이스를 사용하여 테스트를 실행합니다. 테스트는 도구 모음으로 구성되며
추가 하위 도구 모음 및/또는 테스트를 모두 포함할 수 있습니다. 일반적으로
Blockly의 구성요소 (예: toolbox
또는 workspace
)에는 자체 테스트 파일이 있습니다.
여기에는 하나 이상의 도구 모음이 포함됩니다. 각 모음에는 해당 모음의 각 테스트 전후에 각각 호출되는 setup
및 teardown
메서드가 있을 수 있습니다.
테스트 도우미
테스트를 작성할 때 유용할 수 있는 Blockly 관련 도우미 함수가 많이 있습니다. 다음 위치에서 확인할 수 있습니다. 핵심 및 blockly-samples
도우미 함수에는 sharedTestSetup
와 sharedTestTeardown
가 포함됩니다.
테스트 전후에 호출이 필수입니다 (요구사항 참고).
섹션).
sharedTestSetup
:
- sinon 가짜 타이머를 설정합니다(일부 테스트에서는
this.clock.runAll
를 사용해야 함). - Blockly.Events.fire 스텁을 사용하여 즉시 실행합니다 (구성 가능).
defineBlocksWithJsonArray
를 통해 정의된 blockTypes의 자동 정리를 설정합니다.this
컨텍스트에서 액세스 가능: <ph type="x-smartling-placeholder">- </ph>
this.clock
(그러나 복원하면sharedTestTeardown
에서 문제가 발생하므로 복원해서는 안 됨)this.eventsFireStub
this.sharedCleanup
(addMessageToCleanup
및addBlockTypeToCleanup
) (참고: 다음을 사용하여 블록을 정의한 경우addBlockTypeToCleanup
defineBlocksWithJsonArray
)
함수에는 설정을 구성하는 선택적 options
매개변수가 하나 있습니다. 현재
Blockly.Events.fire
를 스텁 처리할지 여부를 결정하는 데만 사용됩니다.
즉시 (기본적으로 스텁 처리됨)
sharedTestTeardown
:
- 워크스페이스
this.workspace
를 삭제합니다(정의된 위치에 따라 다름, 자세한 내용은 테스트 요구사항 섹션 참고). - 모든 스텁을 복원합니다.
defineBlocksWithJsonArray
를 통해 추가된 모든 블록 유형을 정리합니다.addBlockTypeToCleanup
addMessageToCleanup
를 통해 추가된 모든 메시지를 정리합니다.
테스트 요구사항
- 각 테스트는
sharedTestSetup.call(this);
를 가장 바깥쪽에 있는 도구 모음을 설정하고sharedTestTeardown.call(this);
를 파일의 가장 바깥쪽에 있는 도구 모음을 해체하는 데 사용됩니다. - 일반 도구 상자가 있는 작업공간이 필요한 경우
사전 설정된 도구 상자
테스트
index.html
에서 실행되었습니다. 아래에서 예시를 참조하세요. this.workspace
를 올바르게 폐기해야 합니다. 대부분의 테스트에서 가장 바깥쪽 도구 모음에서this.workspace
를 정의하여 이후의 모든 도구 모음에 사용합니다. 경우에 따라 내부 도구 모음에서 정의하거나 재정의할 수 있습니다. 예를 들어 테스트 중 하나에 다른 옵션이 있는 작업공간이 필요합니다. 보다 많아야 함). 또한 테스트가 끝나면 폐기해야 합니다.- 최외곽 모음에서
this.workspace
를 정의하고 다시 정의하지 않으면 추가 조치가 필요하지 않습니다. 자동으로 폐기됩니다.sharedTestTeardown
- 내부 도구 모음에서
this.workspace
를 처음 정의하는 경우 (즉, 가장 바깥쪽 도구 모음에서 정의하지 않은 경우) 수동으로workspaceTeardown.call(this, this.workspace)
를 호출하여 폐기합니다. 해체되는 것 같네요. - 가장 바깥쪽 모음에서
this.workpace
를 정의한 후 내부 테스트 모음에서 재정의하는 경우 먼저workspaceTeardown.call(this, this.workspace)
를 호출하여 재정의하기 전에 최상위 모음에 정의된 원래 워크스페이스를 해체해야 합니다. 나 또한 이번에도workspaceTeardown.call(this, this.workspace)
을(를) 해체했습니다. 이용할 수 있습니다.
- 최외곽 모음에서
테스트 구조
단위 테스트는 일반적으로 정렬, 실행, 어설션으로 요약할 수 있는 정해진 구조를 따릅니다.
- 정렬: 테스트 중인 동작에 필요한 실제 환경의 상태와 조건을 설정합니다.
- Act: 테스트 대상 코드를 호출하여 테스트 중인 동작을 트리거합니다.
- 어설션: 올바름을 확인하기 위해 반환 값 또는 모의 객체와의 상호작용에 관해 어설션합니다.
간단한 테스트에서는 정렬해야 할 동작이 없을 수도 있고 어설션 단계는 테스트 중인 코드에 대한 호출을 어설션을 만듭니다. 더 복잡한 경우에는 이 세 단계를 따르는 것이 테스트를 더 읽기 쉽게 만듭니다.
다음은 테스트 파일의 예시입니다(실제 파일에서 단순화됨).
suite('Flyout', function() {
setup(function() {
sharedTestSetup.call(this);
this.toolboxXml = document.getElementById('toolbox-simple');
this.workspace = Blockly.inject('blocklyDiv',
{
toolbox: this.toolboxXml
});
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('simple flyout', function() {
setup(function() {
this.flyout = this.workspace.getFlyout();
});
test('y is always 0', function() {
// Act and assert stages combined for simple test case
chai.assert.equal(this.flyout.getY(), 0, 'y coordinate in vertical flyout is 0');
});
test('x is right of workspace if flyout at right', function() {
// Arrange
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
viewWidth: 100,
});
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_RIGHT;
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_RIGHT;
// Act
var x = this.flyout.getX();
// Assert
chai.assert.equal(x, 100, 'x is right of workspace');
});
});
});
이 예에서 주의할 사항은 다음과 같습니다.
- 스위트에는 추가
setup
및teardown
메서드가 있는 다른 스위트가 포함될 수 있습니다. - 각 모음 및 테스트에는 설명이 포함된 이름이 있습니다.
- Chai 어설션은 코드에 관한 어설션을 만드는 데 사용됩니다.
- 다음 경우에 표시될 문자열 인수(선택사항)를 제공할 수 있습니다. 있습니다 이렇게 하면 손상된 테스트를 더 쉽게 디버그할 수 있습니다.
- 매개변수의 순서는
chai.assert.equal(actualValue, expectedValue, optionalMessage)
입니다.actual
와expected
를 바꾸는 경우 오류 메시지가 이해되지 않을 것입니다.
- Sinon은 실제 코드를 호출하고 싶지 않을 때 메서드 스텁을 만드는 데 사용됩니다. 포함
이 예에서는 실제 측정항목 함수를 호출하지 않습니다. 왜냐하면
이 테스트와 관련이 없습니다. Google은 검색 결과가 사용되는 방식에만 관심이 있으며,
테스트 중인 메서드입니다. Sinon은
getMetrics
함수를 스텁하여 테스트 어설션에서 쉽게 확인할 수 있는 미리 준비된 답변입니다. - 각 모음의
setup
메서드에는 모든 테스트에 적용되는 일반 설정만 포함되어야 합니다. 특정 동작에 관한 테스트가 특정 조건에 의존하는 경우 해당 조건은 관련 테스트에 명확하게 명시되어야 합니다.
디버깅 테스트
- 브라우저에서 테스트를 열고 개발자 도구를 사용하여 브레이크포인트를 설정하고 테스트가 예기치 않게 실패하거나 통과하는지 조사할 수 있습니다.
테스트 또는 모음에서
.only()
또는.skip()
를 설정하여 해당 테스트 세트만 실행하거나 테스트를 건너뜁니다. 예를 들면 다음과 같습니다.suite.only('Workspace', function () { suite('updateToolbox', function () { test('test name', function () { // ... }); test.skip('test I don’t care about', function () { // ... }); }); });
코드를 커밋하기 전에 이를 삭제해야 합니다.
블록 생성기 테스트
각 블록에는 자체 단위 테스트가 있습니다. 이 테스트는 블록이 제대로 작동하지 않습니다.
- Firefox 또는 Safari에서
tests/generators/index.html
를 로드합니다. Chrome 및 Opera에는 로컬 'file://' 시스템에서 테스트를 로드하지 못하도록 하는 보안 제한사항이 있습니다(문제 41024 및 47416). - 드롭다운 메뉴에서 테스트할 시스템 관련 부분을 선택합니다. '로드'를 클릭합니다. 블록이 작업공간에 표시됩니다.
- 'JavaScript'를 클릭합니다.
생성된 코드를 복사하여 JavaScript 콘솔에서 실행합니다. 출력이 'OK'로 끝나면 테스트가 통과한 것입니다. - 'Python'을 클릭합니다.
생성된 코드를 복사하여 Python 인터프리터에서 실행합니다. 출력이 'OK'로 끝나면 테스트에 통과한 것입니다. - 'PHP'를 클릭합니다.
생성된 코드를 복사하여 PHP 인터프리터에서 실행합니다. 출력이 'OK'로 끝나면 테스트가 통과된 것입니다. - 'Lua'를 클릭합니다.
생성된 코드를 Lua 인터프리터에서 복사하여 실행합니다. 출력이 'OK'로 끝나면 테스트에 통과한 것입니다. - '다트'를 클릭합니다.
생성된 코드를 Dart 인터프리터에서 복사하여 실행합니다. 출력이 'OK'로 끝나면 테스트에 통과한 것입니다.
블록 생성기 테스트 편집
- 브라우저에
tests/generators/index.html
를 로드합니다. - 드롭다운 메뉴에서 시스템의 관련 부분을 선택하고 '로드'를 클릭합니다. 블록이 작업공간에 표시됩니다.
- 블록을 변경하거나 추가합니다.
- 'XML'을 클릭합니다.
- 생성된 XML을
tests/generators/
의 적절한 파일에 복사합니다.