개발 이론 43

[웹 서비스] OAuth 2.0

OAuth 2.0외부 웹 서비스 계정을 이용하여 해당 서비스 권한을 간접적으로 획득하여 나의 웹 서버에서 활용하고자 할 때,외부 웹 서비스에 나의 웹 서버를 인증하는 프로토콜 나의 서비스가 유저의 구글, 야후, 카카오 등 대표 가능한 웹 서비스의 이메일 주소를 이용하고자 한다.유저의 이메일 주소를 알 수 있다면 나의 웹 사이트에서는 따로 이메일 가입을 할 필요 없이 해당 외부 웹 서비스 계정 정보를 이용하여 유저를 특정하고 계정으로 사용할 수 있을 것 이다. 참여자 서비스를 이용하고자 하는 유저 (resource owner) : 내 서비스가 참조하고자 하는 자원 (이메일 주소)를 소유한다.내 서비스 (client) : 유저의 정보를 활용하고자하는 주체. 웹 서비스가 될 수도 있고 앱 어플리케이션 자체가 ..

개발 이론/Web 2024.12.28

[C#] Provider(공급자) - Observer(관찰자) 패턴

Provider - 이벤트를 발생시키면서(제공하면서) Observer를 관리하는 개체 자신이 관리하고 있는 Observer에 대하여 Subscribe하는 방법을 갖고 있고 이벤트 발생 함수를 invoke 한다. Observer - Provider가 발생시키는 이벤트를 구독한다. Observer는 Provider에 Subscibe 함수로 구독을 실행하고 그 반환 Unsubscribe 클래스 개체를 소유한다. Observer는 원할 때 Unbsubscribe 개체 인스턴스를 이용하여 구독을 취소한다. C# Provider는 IObserable 인터페이스를 구현한다. public interface IObservable { IDisposable Subscribe(IObserver observer); } IDis..

[단위 테스트] 데이터베이스 테스트

통합 테스트에서 중요한 의존성으로 취급되는 데이터베이스를 효과적으로 테스트하는 방법을 알아본다. 통합 테스트를 위한 데이터 베이스 준비 - 개발을 위한 데이터 스키마 관리 데이터베이스 스키마는 버전별로 항상 형상관리에 저장되어야 한다. - 데이터베이스 배포 방식 상태 기반 데이터 베이스 배포 방식 vs 마이그레이션 기반 데이터 베이스 배포 방식 상태 기반 방식 개발 내내 관리 되는 모델 데이터베이스가 존재. 배포 중 비교 도구가 스키마 차이를 인식하여 차이에 대한 업데이트를 운영 데이터베이스에 적용하기 위한 스크립트를 만들어낸다. 비교 도구는 불필요한 테이블을 삭제하고 새 테이블을 생성하고 컬럼명을 바꾸는 등 모델 데이터베이스와 동기화하는데 필요한 작업을 수행한다. 마이그레이션 기반 방식 데이터베이스 기..

[단위 테스트] 목 활용하기

테스트 대상 시스템과 외부 의존성간 상호작용을 검증하기 위해 사용되는 목 활용 모범 사례를 알아본다. CRM 예제에서 목의 사용 TEST(TestUserController, 통합_테스트_이메일_변경_사내도메인에서_외부도메인으로) { // given auto db = new Database(string("connection")); auto insertUser = User::CreateUser("user@mycorp.com", UserType::Employee); auto insertCompany = Company::CreateCompany("mycorp.com", 1); db->SaveUser(insertUser); db->SaveCompany(insertCompany); auto messageBusMoc..

[단위 테스트] 통합 테스트

통합 테스트 단위 테스트가 아닌 모든 테스트 ex) 여러 의존성을 걸친 로직을 테스트 하는 것 vs 단위 테스트 : 빠르게 수행되는 단일 동작 단위를 검증 좋은 통합 테스트는 높은 회귀 방지율과 훌륭한 리팩토링 내성을 가진다. 테스트 피라미드 단위 테스트로 갈 수록 테스트 개수가 많아야한다. 위로 갈수록 만드는 비용이 커지지만 잘 만든 테스트는 시스템 전체의 정확성을 보장한다. 빠른 실패 원칙과 통합 테스트 지난 테스트를 위한 리팩토링 예제의 마지막에서 변경될 이메일 주소가 같은 경우 이메일을 변경할 필요가 없으므로 이른 확인을 통해 Company 데이터 베이스 접근을 안하게 하는 로직으로 최적화 하였다. bool UserController::ChangeEmailV3(int userId, string n..

[단위 테스트] 단위 테스트 리팩토링

어떤 코드를 리팩토링 할 것인가? -> 어떤 코드가 중요한 지 파악한다. 복잡도 혹은 도메인 유의성 - 코드의 분기가 얼마나 많은가 - 프로젝트의 문제 도메인에 대해 얼마나 의미 있는가 협력자 수 - 클래스 또는 메서드가 가진 협력자 수 - 가변 의존성 혹은 외부 의존성 리팩토링 목표 지나치게 복잡한 코드를 리팩토링 하여 협력자수를 줄이거나 복잡도를 줄이는 방향으로 함 험블 객체 험블 객체 : 테스트 하기 어려운 부분을 험블 객체로 이동하여 의존성을 분리 -> 지나치게 어려운 코드를 만드는 의존성을 테스트 로직에서 제거해야함 -> 험블 객체라는 얇은 래퍼 클래스를 통해 의존성을 분리 함수형 아키텍처에서 코드 유형 분류 도메인 모델 및 알고리즘 : 함수형 코어 및 도메인 계층 컨트롤러 : 가변 셸 및 어플..

[단위 테스트] 단위 테스트 스타일

단위 테스트 스타일 출력 기반 테스트 상태 기반 테스트 통신 기반 테스트 출력 기반 스타일 테스트 대상 시스템 SUT에 입력을 넣고 생성되는 출력을 점검하는 방식 "함수형 프로그래밍" -> 사이드 이펙트가 없는 방식 상태 기반 스타일 작업이 완료된 이후 상태를 확인하여 검증하는 방식. SUT, 협력자 혹은 데이터 베이스나 파일 시스템과 같은 외부 의존성 등의 상태를 확인. 통신 기반 스타일 테스트 대상과 협력자간의 통신을 검증한다. 출력 기반 vs 상태 기반 vs 통신 기반 출력 기반이 가장 단순하고 유지 보수하기 쉽다. 구현 세부사항과 결합이 거의 없다. 상태 기반은 거짓 양성이 되기 쉽다. 테스트 코드와 제품 코드의 결합도가 높아지기 때문. 통신 기반 규모가 있고 복잡하여 유지 보수하기 어렵다. 출력..

[단위 테스트] 목과 테스트 취약성

Mock 목과 테스트 취약성 목과 스텁의 구분 - 테스트 대역 유형 테스트 대역 : 더미, 스텁, 스파이, 목, 페이크 목 : 외부로 나가는 상호작용을 모방하고 검사하는 것에 도움. SUT가 상태를 변경하기 위해 의존성을 호출. 스텁 : 내부로 들어오는 상호작용을 모방하는데 도움. SUT가 입력 데이터를 얻기 위한 의존성을 호출. ex) 이메일 발송 -> SMTP 서버 (목 : STMP 서버 상태를 변경) 데이터 검색 SUT가 갖는 의존성을 준비시키는 것이지, 의존성을 준비하는 것을 검증해야할 만큼 의미가 있는 행위가 아니다. -> 과잉 명세, 거짓 양성으로 이어지며 리팩토링 내성을 약화 시킨다. CQS Command Query Separation (명령 조회 분리) 모든 메서드는 명령이거나 조회이어야만..

[단위 테스트] 좋은 단위 테스트의 4대 요소

좋은 단위 테스트를 작성하기 위한 4대 요소 -> 회귀 방지 -> 리팩토링 내성 -> 빠른 피드백 -> 유지 보수성 회귀 방지 간단히 말해서 버그를 방지하는 테스트 코드를 작성하는 것이다. 회귀 방지는 코드의 복잡도, 전체 실행되는 코드 양, 도메인의 중요성에 따라 긴밀하게 작성되어야 한다. 리팩토링 내성 테스트 코드가 테스트하는 실제 로직을 리팩토링 했을 때, 테스트 결과가 빨간불이 나오면 안된다. 이는 테스트 코드의 품질과 높은 연관이 있다. - 거짓 양성 False Positive 거짓 양성으로 판별되는 테스트 코드는 실제 코드가 기능적으로 정상이지만 테스트 결과는 실패를 반환하는 것을 의미한다. "높은 회귀 방지율" 좋은 단위 테스트는 기능 고장이 실제 배포 전에 테스트를 통해 실패가 되어 미리 ..

[단위 테스트] 단위 테스트 구조

좋은 단위 테스트 작성하기 1. AAA 패턴 사용하기 - Given/When/Then으로 지칭하기도 한다. 2. 테스트 코드에서 if 문은 사용하지 말라 - 테스트에서 케이스가 생기는 if문 자체가 안티 패턴이다. 3. 준비 (Arrange) 구절 - 3가지 구절에서 보통 가장 길다. 적절한 디자인 패턴으로 리팩토링을 하여 코드 줄 수를 줄인다. 4. 실행 (Act) 구절 - 실행 구절이 한 줄 인 경우를 피하라. 두 줄 이상의 코드를 호출해야한다면 API 설계가 잘 못 된 것이다. 5. 검증 (Assert) 구절 - 적절한 객체 동등비교 equaltiy 논리를 구현하고 검증 구절을 간소화 한다. 6. 검증 대상 객체 (SUT) - SUT를 지칭하는 변수를 sut라고 작성하는 등 SUT를 구별한다. 테스..