계약 테스트를 통한 시간 절약

안녕하세요!오늘의 주제는 계약 구동 테스트입니다.
우리가 시간을 쓰는 방식은 매우 중요하다.
그것은 우리의 생활에서 매우 중요하고, 우리가 합작하는 회사에도 매우 중요하다.
비생산적인 활동에 투입되는 시간을 최소화하고 새로운 아이디어를 구축하는 데 걸리는 시간을 극대화하는 것이 우리의 최대 이익에 부합된다고 생각합니다.

Ok, this is pretty general and someone would even say it's just common sense. What does it have to do with Contract testing?


여기서 내가 말하고자 하는 것은 많은 상황에서 우리는 단원 테스트를 작성할 수 있으며, 작성단에서 끝까지 테스트하거나 수동 테스트를 하지 않는다.
단원 테스트 세트의 일부로서 우리는 서로 다른 구성 요소의 통합을 테스트함으로써 피드백 순환을 가속화시켜야 한다.

계약 테스트 101


두 실체가 통신할 때 공급업체 API의 변경은 모든 소비자에게 고장을 초래할 수 있다.

I have partially touched this topic when I discussed about , indeed I think Contract testing is a way to make our services more Robust without giving up on development speed.


우리 어떡하지?우리는 통합 테스트/끝에서 끝까지 테스트/수동 테스트를 작성합니다.
이런 테스트는 생산이 끝나기 전에 오류를 잡는 데 도움이 되지만 단점도 있다.
  • 을 실행하려면 인프라 시설 설치, 응용 프로그램 배치 등이 필요하다.
    단원 테스트보다 훨씬 느리다. 왜냐하면 이것은 우리가 다른 서비스를 호출하고 네트워크 호출을 하며 데이터베이스를 사용하는 곳이기 때문이다.
    우리는 그것들이 매우 느리고 모든 것을 준비해야 한다는 것을 알고 있기 때문에, 우리는 통상적으로 단원 테스트를 사용하는 것처럼 그것들을 빈번하게 운행할 수 없다.
  • 의 첫 번째 의미는 편차 피드백 회로를 증가시켰다는 것이다.
  • 우리가 다른 개발자와 같은 파이프를 공유하기 때문에 통합 테스트 실패가 반드시 우리가 파이프를 파괴했다는 것을 의미하는 것은 아니다.따라서 발생한 일을 조사하는 데는 더 많은 시간이 필요하다.
  • 계약 테스트의 구체적인 예시를 연구하기 전에 테스트 피라미드를 살펴보자.

    피라미드는 하나의 도형으로 우리가 각 유형에 대해 얼마나 많은 테스트를 해야 하는지를 나타낸다.아래에 단원 테스트가 있습니다. 이것은 비례에 따라 더 많은 단원 테스트를 작성해야 한다는 것을 의미합니다.
  • 그들은 우리의 코드가 격리되어 실행될 때 정확하게 실행될 수 있도록 확보한다
  • 작성이 쉽고 실행 속도가 빠르다
  • 코드 라이브러리에 대한 코드 변경이나 의존항을 업데이트할 때마다 우리는 많은 코드를 작성하고 실행합니다.
    내가 말한 집적 테스트와 끝에서 끝까지 테스트를 토대로 피라미드의 꼭대기에 놓여 있는 것도 이상할 게 없다.

    인스턴스


    계약 테스트가 아닌 계약 테스트를 사용하는 구체적인 예시를 살펴보자.

    예제 1

    Context: 클라이언트 간 서비스 통신Scenario: ReactJs 응용 프로그램으로 사용자를 위해 대기사항 목록을 관리합니다.ToDo 목록은 서버에 정렬되어 전송되며 서버는 정보를 S3에 저장합니다.What we want to test: 코드의 어떠한 변경도 시스템의 회귀를 초래하지 않습니다. 즉, 우리는 서버에서 받은 업무 목록을 반서열화하여react 구성 요소에 표시할 수 있습니다.
    대기사항 목록은 다음과 같습니다.
    export class TodoList {
        items: Item[]
    
        constructor(items: Item[] = []) {
            this.items = items;
        }
    }
    
    // ......
    // And this an item of our TodoList
    
    export class Item {
        constructor(public description: string = '', 
                    public isChecked: boolean = false) {}
    }
    
    코드 중 어느 곳에서, 우리는 TodoList를 가져와 보기 상태를 반서열화하고 업데이트하기 위해 http 요청을 보냈다.

    메서드 1 (나쁨)


    우리는 종합적인 테스트를 작성할 수 있다.
  • 브라우저 열기(각도기,selenium 또는 유사한 도구 사용)
  • react 응용 프로그램 요청
  • 일부 항목을 대기사항 목록에 추가
  • 대기사항 목록 저장
  • 업무 목록 다시 얻기
  • ToDo 작은 위젯의 정보가 정확하고 다른 오류가 발생하지 않았다고 단언합니다.
  • 이것이 바로 우리가 쓰고 싶은 것이다.그것은 느리고 취약하다.
    우리는 계약 테스트를 사용하여 끝까지 테스트를 피할 수 있다.

    방법 2 (양호)


    우선, 우리는 업무 대기 항목 목록을 위해 계약을 하나 만듭니다.
    우리가 사용할 도구:
  • 유닛 테스트용 Jest(다른 유닛 테스트 도구는 모두 작동 가능)

  • Typescript-json-schema Json 모드의 대기 사항 목록 변환

  • Json schema validator 당사의 대기 사항 목록이 계약을 준수하는지 테스트하기 위해
  • 첫 번째 테스트를 실행할 때 계약을 만드는 실용적인 함수를 정의합니다.
    getOrCreateContract = (instance, filename) => {
        if (schemaDoesNotExist(filename)) {
            // TJS comes from the Typescript-json-schema lib
            const program = TJS.getProgramFromFiles([resolve(filename)], {}, basePath);
            const schema = TJS.generateSchema(program, instance, settings);
            saveSchema(CONTRACT_FOLDER, filename);
    
            return schema;
        }
    
        return getSchema(CONTRACT_FOLDER, filename);
    };
    
    우리의 업무 목록을 위한 계약서는 다음과 같다.
    {
        "$schema": "http://json-schema.org/draft-06/schema#",
        "definitions": {
        "Item": {
            "properties": {
                "description": {
                    "default": "",
                        "type": "string"
                },
                "isChecked": {
                    "default": false,
                        "type": "boolean"
                }
            },
            "type": "object"
        }
    },
        "properties": {
        "items": {
            "items": {
                "$ref": "#/definitions/Item"
            },
            "type": "array"
        }
    },
        "type": "object"
    }
    
    이제 계약 테스트를 작성해 보겠습니다.
    describe('ToDo List', () => {
        test('respect contract', () => {
            let todo = new TodoList([
                new Item('contract tests', true)
            ]);
    
            let contract = getOrCreateContract(todo, 'TodoList.schema.json');
            let contractValidator = new Validator();
            let respectContract = () => {
                contractValidator.validate(todo, contract);
            };
    
            expect(respectContract().error().length).toBe(0);
        });
    });
    
    
    위의 단말기부터 단말기까지의 테스트에 비해 이 테스트는 우리에게 완전히 같은 자신감을 제공하지만, 속도가 더 빨라서 진정한 의존항과 통신할 필요가 없다.
    분명히 어떤 경우, 우리는 계약을 갱신하기를 희망한다.예를 들어, 우리는 기존 약정을 덮어쓰기 위해 명령행 매개 변수를 추가할 수 있다.

    예제 2

    Context: 서비스 대 서비스 통신
    나는 댓글이 너무 길다고 생각한다.서비스 사용은 서비스 통신의 결과에 대해 확실히 더 많은 개념을 도입해야 하기 때문에 나는 후속 글에서 예시를 작성할 것이다.

    결론


    집적 테스트는 테스트 피라미드에서 중요한 위치를 차지하지만, 때때로 우리는 그것들을 과도하게 사용한다.
    계약 테스트는 우리의 시간을 절약할 수 있습니다!
    만약 당신이 이 화제에 흥미가 있다면 저에게 알려주세요!
    이것은 내가 서비스가 서비스에 대한 소통에 관한 후속 게시물을 써야 하는지 이해하는 데 도움을 줄 것이다.
    감사합니다.
    니콜라

    좋은 웹페이지 즐겨찾기