한국어로 BDD 코드 작성하기

요즈음 식탁보 프로젝트의 코드를 대대적으로 리팩토링하면서, MVVM, IoC/DI 기능을 마음껏 적용해보고 있습니다. 약 1.5주 동안 작업이 거의 마무리 단계에 진입하면서, 이제 마지막으로 테스트 코드 작성을 어떻게 해보면 좋을까 고민하다가, 전부터 생각만하던 SpecFlow를 도입해보고 있는 중입니다.

그러다, SpecFlow가 Gherkin이라는 언어를 기반으로 기능을 제공한다는 것을 알게되었고, 더 나아가서 Gherkin은 영어 뿐 아니라 한국어를 사용하여 문법을 표현하는 것도 잘 지원한다는 것을 알게 되어 기능을 시험해보니 상당히 괜찮은 것 같습니다!

#language: ko-KR
기능: ResourceResolver

기능에 대한 간단한 설명을 이곳에 남깁니다.
한국어 문법 참고 - https://velog.io/@clarekang/cucumber-kr-introduce

시나리오: 프로그램의 최신 정보를 가져온다.
먼저 다음의 리포지터리에서 정보를 가져오려 한다.
  | 소유자 이름    | 리포지터리 이름   |
  | yourtablecloth | TableCloth        |
만일 버전 정보를 가져오는 함수를 호출하면
그러면 GitHub에 출시한 최신 버전 정보를 반환한다.

시나리오: 카탈로그 문서를 불러온다.
만일 카탈로그 문서를 불러오는 함수를 호출하면
그러면 카탈로그 문서에 1개 이상의 사이트 정보가 들어있다.
그리고 마지막으로 카탈로그를 불러온 날짜와 시간 정보를 확인할 수 있다.


대략적인 구조는 이렇습니다. 위와 같이 Feature 문서를 작성하면, Binding 어트리뷰트를 붙인 클래스를 정의하고, 각 단계 (줄마다 앞에 쓰인 ‘만약’, ‘그러면’, ‘그리고’ 가 각각 하나의 단계를 의미합니다.) 뒤에 쓰인 문장 1개 또는 여러 개에 매칭되는 단계 함수에 원하는 테스트 코드를 작성하여 유닛 테스트를 완성하는 방식입니다.

이 때, SpecFlow VS Addin이 feature 파일의 내용을 토대로 한글이 포함된 메서드 코드를 자동으로 작성해주기도 하는데, C#은 처음부터 유니코드 인코딩으로 저장된 코드 파일을 처리할 수 있도록 설계되었으므로 한국어로 멤버 변수나 클래스 이름을 작명하더라도 문제가 되지 않습니다.

그리고 유닛 테스트 프레임워크는 xUnit을, DI/IoC 컨테이너로 저는 Microsoft Extensions 사용을 선호하는데, SpecFlow용 플러그인이 양쪽 모두 준비되어있어서 다음과 같이 IoC 컨테이너 구성이 가능합니다.

using Serilog;
...
using TableCloth.ViewModels;

namespace TableCloth.SpecFlow.Support;

public static class ScenarioDependencies
{
    [ScenarioDependencies]
    public static IServiceCollection CreateServices()
    {
        var services = new ServiceCollection();

        // Add Logging Service
        services.AddLogging(c => c.AddSerilog(dispose: true));

        // Add HTTP Service
        services.AddHttpClient(nameof(TableCloth), c => c.DefaultRequestHeaders.Add("User-Agent", StringResources.UserAgentText));
...
        return services;
    }
}

코드 작성을 마치고, 빌드를 한 번 수행하면 Test Discovery가 되면서 다음과 같이 유닛 테스트 진행이 가능합니다.

기존 유닛 테스트와 동일한 기능을 제공하므로, 유닛 테스트 단계 안으로 디버거를 부착해서 문제를 진단하는 것도 가능하니 편하게 쓸 수 있어서 좋은 것 같습니다.

BDD에 관한 자세한 내용은 아래 두 개 문서를 보시면 유용할 것 같습니다.

Cucumber 한글 시나리오 작성하기 #introduce (velog.io)
SpecFlow와 FluentAssertions를 이용하여 BDD 적용하기 #1 | Aliencube

7개의 좋아요

오 이거 신기하군요…