오늘은 BDD 방식으로 iOS 유닛 테스트를 작성하기 시작했습니다. guard
진술과 100 % 코드 커버리지에 관한 질문이 있습니다.Guard Statement 테스트 통과를위한 테스트 커버리지 방법
Data
에서 Customer
개체로의 변환을 처리하는 다음 코드가 있습니다.
internal final class func customer(from data: Data) -> Customer? {
do {
guard let jsonDictionary = try JSONSerialization.jsonObject(with: data, options: []) as? Dictionary<String, Any> else {
return nil
}
var customerFirstName: String? = nil
var customerLastName: String
if let firstName = jsonDictionary["first_name"] as? String {
customerFirstName = firstName
}
guard let lastName = jsonDictionary["last_name"] as? String else {
return nil
}
customerLastName = lastName
return Customer(firstName: customerFirstName, lastName: customerLastName)
} catch {
return nil
}
}
우리 백엔드를 만들었을 때 일부 고객에게는 이름과 성이 포함 된 성이 주어졌습니다. 그래서 고객의 이름은 선택 사항입니다. 그들의 성명은 last_name
의 값일 수 있습니다.
내 코드에서 고객의 성은 선택적이지만 성이 필수입니다. 네트워크 요청에서 수신 된 JSON에 성이 반환되지 않으면 고객을 만들지 않습니다. 또한 Data
을 Dictionary
으로 직렬화 할 수없는 경우 고객이 생성되지 않습니다.
둘 다 두 시나리오를 테스트하기 위해 사용하고있는 고객 정보가 포함 된 두 개의 JSON 파일이 있습니다.
이{
"first_name": null,
"last_name": "Test Name",
}
다른 하나는 먼저 JSON의 이름이 포함되어 있습니다 : 빠르고 민첩한를 사용하여 내 단위 테스트에서
{
"first_name": "Test",
"last_name": "Name",
}
를, 내가 처리
하나는 JSON에는 이름을 포함하지 않는다 첫 번째 이름을 사용할 수 없을 때 Customer
을 만들면 그 이름은 다음과 같습니다.
override func spec() {
super.spec()
let bundle = Bundle(for: type(of: self))
describe("customer") {
context("whenAllDataAvailable") {
it("createsSuccessfully") {
let path = bundle.path(forResource: "CustomerValidFullName", ofType: "json", inDirectory: "ResponseStubs")!
let url = URL(fileURLWithPath: path)
let data = try! Data(contentsOf: url)
let customer = DataTransformer.customer(from: data)
expect(customer).toNot(beNil())
}
}
context("whenMissingLastName") {
it("createsUnsuccessfully") {
let path = bundle.path(forResource: "CustomerMissingLastName", ofType: "json", inDirectory: "ResponseStubs")!
let url = URL(fileURLWithPath: path)
let data = try! Data(contentsOf: url)
let customer = DataTransformer.customer(from: data)
expect(customer).to(beNil())
}
}
}
}
이것은 반환 된 JSON에 이름이 없거나 존재할 때 Customer
을 생성합니다.
데이터가 유효한 JSON 개체로 바뀔 수 있기 때문에 내 코드가 else
절의 else
절을 누르지 않으면 BDD를 사용하여이 방법의 코드 적용 범위를 100 %까지 어떻게 늘릴 수 있습니까? 다른 .json
파일을 Customer
이 생성되지 않고 Customer
이 생성되지 않도록 last_name
을 포함하는 파일뿐만 아니라 .json
파일이 생성되지 않도록 JSON 객체로 변환 할 수없는 데이터를 추가해야합니까?
나는 "100 % 코드 적용 범위"개념을 과소 평가하고 있습니까? guard
문장의 else
절을 테스트해야 할 필요가 있습니까? BDD 방법을 사용하여 적절한 방법을 사용하고 있습니까?
@JonRein 통찰력에 감사드립니다! 나는 사실을 모른 채 시험을 쓴다고 어떻게 결론 내 렸습니까? 그것이 바로 내가 한 일이지만, 당신을 그 결론에 이르게 한 이유가 궁금합니다. 나는 확실히 당신의 개념을 연구하고 더 나은 이해를 얻기를 바라고 있습니다. –
@NickKohrn 코드가 테스트 주도 일 때 테스트를 만족하지 않는 코드를 작성하지 않기 때문에. 그래서 당신은 결국 "나는 어떤 코드를 가지고있다. 어떻게 커버 할 수 있는가?"라고 묻지는 않는다. –