ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C#, xUnit으로 테스트
    프로그래밍/기록, 개념, 용어 2022. 11. 27. 16:49
    반응형

    NET CORE로 개발하는 프로젝트에 테스트를 적용하고 했습니다.

    반복적으로 테스트 하던 부분들을 줄이고, 이슈가 발생하면 그 이슈를 테스트 케이스로 만듦으로서 반복적으로 발생하는 이슈를 조금씩이라도 줄여가기 위함입니다.

    테스트 프레임워크로는 xUnit이 적합해보여 그것을 사용하자고 생각했습니다.

     

    xUnit 테스트 프로젝트 만들기.

    새 프로젝트 추가에서 xUnit을 검색하고, 그것으로 프로젝트를 만들면 됩니다.

    만들어진 프로젝트엔 UnitTest1.cs 라는 파일이 있습니다.

     

    테스트 할 메소드 지정하기.

    테스트 할 메소드에 [Fact] 애트리뷰트를 지정하기만 하면 자동으로 테스트 메소드가 됩니다.

    테스트는 기대한 값과, 실제 연산된 값을 비교함으로서 이루어지는데, 비교를 하려면 Assert로 검색되는 메소드들을 이용합니다.

    그리고 파일 또는 프로젝트에서 테스트 실행을 누르면 테스트가 됩니다.

    테스트 결과는 테스트 탐색기에서 확인할 수 있습니다.

    만약 테스트 탐색기가 보이지 않으면 보기 - 테스트 탐색기를 눌러 테스트 탐색기 창을 띄우면 됩니다.

     

    기존 프로젝트의 기능들을 가져와서 테스트하기.

    프로젝트에서 종속성 - 프로젝트 참조 추가 - 프로젝트를 선택하면 다른 프로젝트에 정의된 것들을 사용할 수 있습니다.

     

    데이터베이스를 포함하는 테스트.

    테스트용 데이터베이스를 구성하고, 그것을 이용하는 테스트를 진행하려면 Fixture를 이용합니다.

    Fixture에는 특정 상태로 Db를 초기화한다던지, 테이블을 구성한다던지, 테스트를 위한 데이터셋을 쌓는 등의 모든 동작이 포함됩니다. 

    기존 프로젝트의 기능들을 가져와서 테스트하기에서 BloggingContext라는 DbContext가 정의되어 있다고 가정하면, EnsureDeleted(), EnsureCreated()를 사용해 쉽게 기존 데이터베이스를 제거하고, 새로 생성할 수 있습니다.

    public class TestDatabaseFixture
    {
        // Db 연결을 위한 커넥션스트링
        // 테스트를 위해 사용할 것이니 테스트를 위한 커넥션 스트링을 정의합니다!
        private const string ConnectionString = @"Server=localhost;Database=TestDb;Trusted_Connection=True";
    
        private static readonly object _lock = new();
        private static bool _databaseInitialized;
    
        public TestDatabaseFixture()
        {
            lock (_lock) 
            {// 테스트 중 한 번만 초기화
                if (!_databaseInitialized)
                {
                    using (var context = CreateContext())
                    {
                        // 기존 Db 제거
                        context.Database.EnsureDeleted();
                        
                        // Db 생성
                        context.Database.EnsureCreated();
    
                        // 테이블 데이터를 구성한다.
                        context.Add(new Blog { Name = "Blog1", Url = "http://blog1.com" });
                        
                        context.SaveChanges();
                    }
    
                    _databaseInitialized = true;
                }
            }
        }
    
        public BloggingContext CreateContext()
            => new BloggingContext(
                new DbContextOptionsBuilder<BloggingContext>()
                    .UseSqlServer(ConnectionString)
                    .Options);
    }

     

     

    그리고 Fixture를 이용하는 Test 클래스를 만들면 아래와 같이 합니다.

    public class BloggingControllerTest : IClassFixture<TestDatabaseFixture>
    {
        private readonly TestDatabaseFixture _fixture;
        
        public BloggingControllerTest(TestDatabaseFixture fixture)
        {
            _fixture = fixture;
        }
        
        [Fact]
        public void TestAddBlog()
        {
            using BloggingContext context = _fixture.CreateContext();
            
            var controller = new BloggingController(context);
            
            await controller.AddBlog("Blog", "https://Blog.com");
            
            var blog = context.Blogs.SingleOrDefault(b => b.Name == "Blog");
            
            // 블로그가 추가됐는지 확인
            Assert.NotNull(blog);
            
            //블로그 데이터가 제대로 설정되었는지 확인
            Assert.Equal("https://Blog.com", blog.Url);
        }
    }

     

    반응형
Designed by Tistory.