소프트웨어 공학 (10), Software Testing

2022. 5. 18. 01:06강의 내용 정리/소프트웨어 공학

728x90
반응형

Software Testing

1. Development testing

1) Program testing

큰 틀에서의 프로그램 테스트


(1) 주어진 input과 output에 대한 동작이 제대로 나오는지 확인라는 것이 목적

(2) 여러 이유로 프로그램이 비정상 동작을 할 때 어떤 상황에서 오류가 발생하는지 파악하고 이를 대응하는 것이 목적

 

- 테스트는 다양한 사람과 단계에 걸쳐서 테스트되고, 과거의 혹은 인위적으로 만든 데이터를 투입해서 동작하는지 확인하는 과정이 존재한다. 맨 마지막 단계에서 실 사용자 일부에게 테스트를 진행한다.

- 테스트를 수행함으로서 잘못된 것에 대한 에러나 비정상적인 동작에 대한 예외상황 등, non-functional 부분 등에 대해서도 확인해야한다.

- 무엇을 테스트하는지에 대해 따라 테스트 지표가 달라지기에 이를 정하고 에러를 찾아가는 과정임을 분명히 인지해야한다.

- 테스트는 우리가 생각한 기능이 설계한 요구사항대로 잘 되었는지 확인하고(verification), 사용자가 사용하고 돈을 낼 만한 가치가 있는지(validation)를 맞춰 진행해야한다.


2) Program testing goals

(1) 우리가 생각한 대로 제대로 동작하는가 -> Validation testing

- 개발자와 고객에게 요구사항대로 동작하는지 보여줘서 테스트한다.

- 많은 요구사항 번호들에 대해 각각 구현하고 하나하나마다 최소한 하나 이상 테스팅해야한다. 즉, 명세 모두에 대해 각각 적어도 하나 이상 테스트해야하고, 이를 만족했을 때 제대로 테스트를 해야한다.

- generic software: requirement는 회사가 주로 정의하기에 이에 대한 feature나 복잡한 케이스나 복합 기능 등을 스스로 정의한 테스트 케이스에 대해 진행해야한다.

 

(2) 프로그램이 문제가 있는지 발견한다. -> Defect testing

- 프로그램이 문제가 있는지 확인하는 과정은 생각도 많이해야하고, 초점을 맞췄던 것에서 벗어나서 생각하지 못한 것에 대응하는 것에 집중해야한다. 

- 입력을 제대로 줬지만 잘못된 결과가 나온 상황이나 우리가 원하지 않는 상황, 규격을 맞추지 않는 경우, 느려지는 등 비정상적인 동작들에 대해 찾아내야한다.

 

An input-output model of program


3) Verification vs Validation

(1) Verification

- 확인, 입증, 증명, 검증, 실증

- 주어진 specification에 맞게 프로그램을 만들었는가 -> 입력에 대한 결과를 만들고 있는가

- 개발과 관련된 개발자 관점

- Validation testing과 defect testing은 이에 해당될 수 있다.

 

(2) Validation

- 실증, 확증

- 의미가 있는 프로그램을 만들고 있는가.

- 고객님이 얘기한 것을 가지고 만들었더니 고객님이 봤을 때 의미가 없는 프로그램을 만들 수 있기에 실제로 고객이 원한 것이 아닐 수 있다. 따라서 이를 파악하는 것도 중요하다.

- 유저 테스트를 통한 유저 관점

- 프로토타입이나 피드백을 통한 테스트 과정이 필요하다.


4) V & V confidence

- 개발자는 하나의 상품을 가지고 수많은 고객을 만족시켜야한다. 

 

(1) Software purpose (소프트웨어 목적)

- 소프트웨어의 목적에 맞고, 이미 정의한 것(Specification)에 만족하는지 확인해야한다. 

 

(2) User expectations (사용자의 기대감)

- 사용자는 첫번째 소프트웨어를 확인할 때의 기대감이 없고, 의심의 눈으로 볼 수 있다. 이를 고려해서 의심하지 않도록 충분히 안정적이고, 돈이 될만한 가치가 있다는 것을 validate해야한다.

 

(3) Marketing Environment(마케팅 환경)

- 우리가 만들고자하는 소프트웨어를 만들 수 있는 곳은 여러 곳에서도 존재한다. 이에 따라 개발 기간이 짧아지게 되는데, 이때 테스트할 시간이 줄어들 수밖에 없다.  또한 테스트 중에서도 defect testing이 더 줄어들 수밖에 없다. 따라서 프로그램을 일단 만들고 이를 출시할 수밖에 없다. 또한 이는 User expectations에 영향을 미친다. 하지만 유저가 기대하는 바는 만족시켜야한다. 따라서 이를 고려하기 매우 어렵다.

- 마케팅을 하는 사람들이 시기를 조절해야할 때 우선순위를 고려해서 프로그램 테스트를 조절해야한다.

- 버그가 없는 소프트웨어는 없고, 무한정 테스트를 할 수도 없고, 프로그램을 시장에 내놓는 시점에서 반드시 테스트해야하는 것들, 언젠가 테스트해야할 것들 등을 고려해야한다. 또한 이는 고객 관점에서 수용할 수 있는 수준으로 고려해야한다. 

 


5) Inspections and testing

(1) Dynamic verification

- 입력을 주고 그거에 따른 결과를 프로그램을 통해 추출하여 테스트한다.

- 테스트 데이터를 주고 원래 specification에 정의한 동작이 제대로 되는지 확인한다.

 

(2) Static verification

- software inspection로 소스코드를 사람이 눈으로 보고 분석하는 것을 의미한다.

- 코드를 실행시키지 않기에 이를 정적이라고 한다.

- 제대로 동작하는지 머릿속으로 확인한다. 코드 리뷰를 통해 누군가가 다른사람이 만든 코드를 봄으로서 떨어지는 성능이나 예외처리, 구조가 어떤지, 재사용 가능성 등에 대해 파악할 수 있다.

- 코딩과정에서도 꾸준히 사용할 수 있다.

 

- inspection은 전 과정에 들어가게 된다.

- pair programming: 같은 프로그램을 두 명이 같이 작성하기도 한다. 다른 개발자가 코드 리뷰를 진행한다.

소프트웨어 테스팅을 했을 때 성능의 병목 구간이 발생한 경우에는 이를 다 같이 확인하곤 한다. inspection

- prototype, 프로그램을 testing할 수 있다.

 

(3) Inspections

- 소스코드를 보면서 예상되는 오동작이나 돌아가지 않을 것들을 찾아낸다.

- 프로그램이 없고, 개발 중이더라도 퀄리티를 높이는 테스트를 할 수 있다.

- 전체적인 과정 속에서 할 수 있기에 대부분 열심히 한다.

- 중요하고 가치있는 작업이다.

- 좋은 코드를 많이 읽고, 오픈 소스 코드를 보면 배울 수 있고 적용할 수 있는 점도 많다.

 

(4) inspections의 장점

- 정적인 과정이고, 코드를 읽어감으로서 프로그램을 현재 있는 상태나 언제든지 확인할 수 있다. 연결이 안되더라도 프로그램을 봐가면서 inspection도 가능하다.

- 사람이 인위적으로 읽고 분석하는 것이기에 비용이 드는 것도 아니다.

- 완성되지 않은 프로그램에 대해서도 수시로 체크하는 것은 좋은 것이다.

- 프로그램 구조가 호환성이 있는지(portability), 유지 가능성, 표준을 맞췄는지 등  non-functional 부분에 대해 동적으로는 찾기 어렵다. 이를 inspection을 통해 확인할 수 있다.

- 정적, 동적 테스트는 서로 보완적인 관계이다.

- 두 기법 모두 V & V 기법으로 쓰인다.

- 내가 만든 프로그램을 실행하고, inspection하는 것을 모두 병행하며 실행한다.

 

(5) Testing

A model of the software testing process

- inspections는 모든 단계에서 사용가능하고

- test는 각 시나리오를 기준으로 테스트 케이스를 정의하고 이를 기준으로 입력에 대한 데이터를 만들고, 이를 기준으로 테스트를 실행하고 이를 활용해 원래 예상한 결과가 제대로 나왔는지 나오지 않았는지를 확인하여 레포트를 만들고 다음 단계로 넘어갈 수 있다.

 

(6) stages of testing

- 테스트는 여러번 진행된다.

(6-1) Development testing

- 소프트웨어를 만든 사람이 테스트한다. 

- 본인 혹은 팀 단위

- 하지만 개발자는 본인의 소프트웨어 입력외의 사항에 대해선 크게 신경쓰지 않고, 각각의 소프트웨어를 합쳐서 에러가 발생할 수 있다. 이에 따라 시험 검증을 위한 팀이 존재에 이에 제출한다.

 

(6-2) Release testing

- Development testing한 것을 모두 묶어서 소프트웨어를 유저에게 주는 중간 단계에 하는 테스트이다. 별도의 전담 테스트 팀이 소프트웨어를 묶어서 유저에게 전달하기 전 단계에 이를 확인한다. 유저의 목소리를 가져오고 소프트웨어가 제대로 구현됐는지 전체적으로 테스트한다.

 

(3) User testing

- 유저에게 소프트웨어를 전달한다. 유저 입장에서, 유저를 대신할 수 있는 사람들을 통해 사용자 입장에서 소프트웨어를 테스트한다.

 


1. Development Testing

1) Development Testing이란?

개발한 팀에서 본인이 만든 소프트웨어를 테스트하는 단계



2) 테스트 단계

(1) Unit testing

- 가장 작은 단계인 함수나 객체, 클래스가 제대로 만들어졌는지 점검(데이터를 읽는 부분, 데이터를 분석하는 부분 등)

- function level, class level

 

(2) Component testing

- 클래스의 인터페이스들이 제대로 이루어졌는지 점검 (함수가 함수의 호출, 머신러닝하는 얘들끼리 잘 돌아가는지, 데이터를 읽는 얘들끼리 잘 돌아가는지 등)

 

(3) System testing

- 모든 것을 모아서 final product level에서 테스트한다.


3) Unit testing

(1) Unit testing이란?

- 독립적인 구성요소를 각각 테스트를 한다.

- 각 객체의 메소드나 attribute와 같은 것을 테스트한다.

- 여러개의 클래스가 묶여 하나의 클래스로 만들어질 때에도 이를 테스트한다.

 

(2) Class test

- 연산자나 메소드가 제대로 동작하는지 확인하는 것이 중요하다.

- 객체가 관리하는 데이터나 클래스 등을 체크하고 수정하는 것이 가능한지 확인한다.

- 우리가 만든 클래스 객체가 가능하면 수많은 케이스에 의해 단련이되면서 어떤 것에도 문제가 없도록 해야한다.

- 객체 지향 기법에선 유전의 법칙을 사용할 수 있는데 베이스 클래스가 무결하지 않기에 객체지향 기법을 사용할 경우에는 에러가 발생할 수 있다.

- 테스트는 에러가 없다는 것을 검증하는 것이 아닌 에러를 찾는 것에 초점이 있다는 것을 주의해야한다.

 

(3) Weatherstation 예시

- weatherstation 하나에 대해 메소드들이 원하는대로 동작하는지 등등을 확인하는 동작이다.

- 메소드에 의해 내부에 데이터가 제대로 유지되고 관리되는지 확인한다.

- 이를 위해 시나리오를 통한 테스트 케이스를 만든다.

- 동적으로 데이터를 만들고 추출하는 과정이 수반된다.

- 우리가 디자인할 때 정의한 시나리오에 맞춰 우리의 클래스에게 event를 준다. 이때 상세설계 시 정의한 시나리오에 맞춰 테스트케이스를 만들고 이를 weatherstation에게 전달한다. 

- 테스트 프로그램이 절차적으로 제대로 동작하는지 하나씩 체크해가는 과정이 있다.


4) Automated testing

(1) Automated testing이란?

- unit testing은 자동화되어서 체크한다.

- 우리가 만든 테스트 프로그램이 알아서 자동으로 프로그램을 만든다.

- 개발하는 프로그램보다 사이즈가 더 커질 수 밖에 없다.

- 각 언어별로 테스트 프로그램을 짜는 프레임워크 또한 존재한다.

- 테스트에 대한 리포트를 만들어야하는데, 테스트 프로그램 프레임워크를 사용하면 일반적으로 도움이 될만한 테스트 결과들을 리포팅 또한 할 수 있다. 

 

(2) 테스트를 할 때 거치는 단계

setup part: 테스트를 하기 위해 setup하는 단계

call part: 테스트를 실행하는 단계

assertion: 테스트 결과가 맞는지, 틀린지 결정하는 단계

 

cf) 테스트 케이스의 종류

- 정상적인 입력에 대해 정상적으로 동작하는가

- 잘못된 동작을 찾아내는 작업

- 여기에 추가로 잘못된 입력이 들어왔을 때 죽지않고 다시 복구할 수 있는 것이 중요하다.

 

(3) testing strategies

Partition testing: 어떤 입력을 줄건지 정한다. ex) 정수형인 경우에는 범위를 설정해야한다.

Guideline-based testing: 회사나 개발자의 경험에 의존해 정형화된 문제점들에 대해 체크한다.

 

(4) Partition testing

- 대표가 되는 특정 값으로 주어지는 것으로 입력할 것이다.

- 입력 값으로 놓치는 게 있다면 실패할 수 있다.

- 전체에 대해 테스트할 수 없기에 군으로 묶어서 대표 값을 샘플링해 태스트를 진행한다. 

Equivalence partitioning

Equivalence partitions

 

- 영역에 인접한 점에 대해서는 반드시 체크해야한다.

 

(5) General testing guidelines

- 에러를 유발하는 input을 줘라 ex) 숫자만 입력하는 것이지만 글자나 특수 기호를 넣어보자

- 범위를 벗어나는 입력을 줘라 ex) 생년월일 -> 1999911111 // 고정사이즈인 배열을 사용하면 죽을 수 있다.

- 입력값을 반복적으로 줘서 업데이트에 문제가 있는지 없는지 확인

- 에러가 발생할 수 있는 상황을 유발해라.

- 계산 결과가 굉장히 크거나 작을 수 있도록 할 수 있어야한다. ex) c++ int 사이즈는 cpu에 따라 다름 // 프로그래밍 언어에서 최댓값과 최솟값을 확인해야한다.

 


4) Component testing

(1) Component testing이란?

- 수많은 객체가 다른 객체를 호출하여 상호작용하는 경우를 테스트한다.

- 하나의 클래스 객체가 바깥과 통신을 하기 위해선 인터페이스가 존재한다.

- 단순히 메소드 호출 뿐만이 아니라 파일을 불러오는 것도 포함될 수 있다.

- 클래스 객체 간에 인터페이스에 초점을 맞춰 확인해야한다.

 

(2) Interaface testing

- 객체 간에 인터페이스를 위해선 다양한 방법이 동원된다.

- 우리 클래스가 제대로 호출되고 제대로 동작하는지 확인해야한다.

 

2-1) interface 방식 메소드를 호출하는 것은 파라미터 interface 방식이라고 볼 수 있다. 클래스를 구성하는 메소드를 호출할 떄 입력 파라미터를 준다. 입력 파라미터로 제대로된 값을 줄 때 제대로 동작하는지, 제대로 된 값을 주지 않을 때 어떤 상황이 발생하는지에 대한 것이 된다.

2-2) Shared memory interfaces: 객체 간에 동일한 컴퓨터 메모리를 사용하는 경우

2-3) Procedural interfaces: 여러 절차들을 한번에 묶어서 수행하는 경우 제대로 지켜져있는지 테스트

2-4) Massage passing interfaces: 컴퓨터가 통신하면서 메세지를 전달하는 경우

- 프로그래밍 경험이 많이 없다면 2-1을 많이 확인하지만 성능을 올리기 위해서는 이 외의 것도 확인하는 과정이 필요하다.

- 개별적인 검증은 모두 unit test에서 되었다고 가정한 뒤 진행하는 것이기에 이전에 문제가 발생하면 이후에도 문제가 발생한다.

 

- 외부에서 테스트 케이스를 보내서 우리의 구성요소들이 제대로 되는지 확인하는 것이 주요한 목적이다.

 

 

(3) interface errors

(3-1) Interface misuse

- 줘야할 파라미터 사이즈를 맞추지 않거나, 파라미터의 순서가 뒤집어진 경우 등 입력 파라미터를 잘못 전달한 경우

(3-2) interface misunderstanding

- 인터페이스를 잘못 이해해서 발생하는 에러. 요구사항을 제대로 따르지 않는 경우 발생할 수 있다. 따라서 문서가 중요하다.

ex) 이진탐색을 해야해서 정렬된 리스트를 전달받는다고 했지만 이를 읽지않아서 unsorted 리스트를 전달하는 경우

 

(3-3) timing errors

- 컴퓨터 메모리에서 write하고 다른 객체에서 load한 뒤 사용해야하는데 미쳐 가져오지 못한 경우, a와 b가 같은 값을 가지고 움직여야하지만 하나가 어긋나기 시작하는 경우

-> 하드웨어에 밀결합된 소프트웨어를 만들 경우에는 1이 0이될 수 있고, 1바이트가 3바이트로 입력이 되는 등 임베디드, 통신, 하드웨어 프로그램 등에서는 timing error가 발생할 수 있다. ex) 아두이노, 컴퓨터에 연결할 떄 board late를 세팅한다. 초당 0과 1을 얼마만큼 보낼지 제대로 정하지 않으면 에러가 발생할 수 있다.

 

 

(4) interface testing guideline

- 전달하는 값의 최대 최솟값, 중간 값을 전달해라. 이때 군이 있다면 그 군의 최대, 최소, 중간 값을 전달해야한다.

- 주소값이 의미 없는 null pointer를 줬을 때 방어할 수 있는지 체크해야한다.

- 제대로되지 않은 것을 줌으로서 죽는지 사는지 확인하는 과정이 필요하다.

- 메세지를 많이 줘서 부하를 굉장히 많이 주는 경우(stress testing) 어떤지 확인해야한다. 이때 죽으면 안된다. 부하가 발생한다면 메세지를 버리고, 우선순위를 처리할 수 있는 과정이 필요하다. 통신에서 매우 중요하다.

- 메모리 공유 시스템에서는 메모리 쓰는 것이 완료된 이후에 이를 읽는 순서가 중요하다. 운영체제에서 프로그램을 짜는 경우에는 내가 쓰는 경우에는 다른 사람이 사용하지 못하게 락을 걸어 사용하는 경우가 존재한다. 혹은 flag라고 해서 A와 B가 공유하는 방법이 존재한다.

- 클래스 간에 정보를 주고받는 것을 확인해야한다.


6) System testing

시스템 단위에서 진행하는 테스트


(1) System testing이란?

- unit testing, component testing 이후에 시스템 단위에서 테스팅을 진행하는 것이다.

- 전부 하나의 시스템으로 추가한다.

- 컴포넌트들 간에 통신이 어떻게 이뤄질지에 대해 이지만 규모가 유저에게 전달할만큼 큰 것이다.

- 개발에 첫 단추를 끊었던 시스템에서 해야할 일을 테스트한다고 생각하면 된다.

 

(2) Syetem and Component testing의 차이

- unit test는 개발팀, component testing은 대부분 개발팀, system testing은 전담팀이 대게 한다.

- 소프트웨어는 COTS한 것들도 우리의 시스템과 통합이 되는지 확인하는 과정이 필요하다.

- 규모를 갖춘 회사는 대부분 개발, 디자인과는 독립된 팀이 작업을 한다.

 

(3) use case testing

- 시스템 테스팅도 use case를 사용해 testing하는 경우가 일반적이다. 

- 어떤 메세지를 주고받아야하는지 절차, 동작 등을 구현하는 경우가 많다.

- sequence diagram에 맞춰서 테스트 프로그램을 짜게 된다.

- 자동화된 소프트웨어에 의해 우리가 만든 소프트웨어를 보내고 받아 리포트를 만드는 과정이 수반된다.

 

 

- 우리가 Weather station을 개발하는 작업을 한다면 그와 관련된 인터페이스에 대해 관리하는 것은 component testing이다.  

- SatComms를 만드는 팀이 다른 팀이라면 Weather station과 만나는 지점까지 연결해 테스트하는 것이 system testing을 하는 것이다.

- 최초의 요구는 information system이 한 것이다.

- weather station은 reportweather 등이 잘 전달되는지 확인하는 것이 중요하다.

 

(4) Sequence diagram

- request를 보내는 사람은 반드시 Ack를 받는다. 또한 이것이 맞는지, 틀린지 확인해야한다. 이는 request report를 하고, 이후에 결과를 전달받는다.

- Weather Station이라면 올바른 결과 확인을 위해 이러한 결과를 미리 가지고 있어야한다. 또한 엉뚱한 요구와 이에 대한 예상 결과도 미리 가지고 있어야한다. 이를 판단할 수 있어야한다.

- component들 간의 intergration과 모든 것들의 통합을 통해 유저의 요구를 받아 제대로된 결과를 전달받았는지 확인하기 위해서 사용한다.

- 다시말해 올바른 요청과 올바른 결과, 잘못된 요청과 그에 대한 결과를 미리 가지고 있어야한다.

 

Testing Policies

- 모든 버그를 찾는것은 불가능한 상황에서 사람 시간 자원은 항상 부족하기에 어디까지 테스트를 할 것인지에 대해 정해야한다. 따라서 버그의 영향이 적은 프로그램을 만드는 것이 중요하다.

Policies 예시

- 시스템을 사용하는 유저 입장에서 보는 메뉴가 있다면 이와 관련된 기능은 모두 확인해야한다. 또한 메뉴의 연결이 있다면 연결된 것을 모두 테스트 해야한다.

- 올바른 요청과 올바른 결과, 잘못된 요청과 그에 대한 결과도 테스트해야한다.

 

 


2. Test-Driven Development TDD

Unit test, Component test, System test를 할 때 유용한 기법으로 테스트를 미리 진행한 뒤 에러가 발생하는 부분을 수정하는 기법을 의미한다.


1) 개념

- 앞서 설명한 Unit test, Component test, System test은 절차이지만 이를 하기위해 유용한 도구이다.

- 최근 개발 방식인 Agile에서는 굉장히 많이 사용한다.

- Specification에 대해 개발 코드를 구현하기 전에 내가 구현할 코드에 대한 테스트코드를 먼저 짜는 것이다. 이후 처음 생각한 입력 결과가 제대로 나오는지 확인한다.

- 코딩과 테스트가 밀결합되어있다. agile에서는 프로그램을 incremental하게 짰다.

- Agile 컨셉의 Tdd는 각 페이즈마다 테스트 코드를 먼저 짜고 이후에 페이즈에 대한 개발 코드를 짠다. 또한 이를 더 쪼개서 클래스 메소드별로 tdd를 사용할 수 있다.

- Plan based나 waterfall도 TDD를 병행해서 사용할 수 있다.

 


2) Test-Driven Development Process

(1) Test-Driven Development Process

- identify new functionality: 테스트를 할 단위를 설정한다.

- 클래스를 하나 만들 때의 멤버 메소드가 열개라고 가정한다.

- 우선 우리가 실행시키고 짜야할 클래스를 정의한다. -> 이후 테스트를 짜고, 바로 테스트를 한다. 이에 따라 fail이 난다.  이러한 것이 TDD 정신이다. 최초에는 클래스에 대한 코드도 작성하기 전에 테스트 코드를 짜서 이를 실행시킨다.  이에 따라 fail이 난다. 이후 fail이 발생한 것을 implement functionality and refactor에서 짠다. 이후 제대로 코드를 짰다면 pass되고, 두번째 메소드에 대해서 test를 짠 뒤, 이를 run하여 에러가 발생한다. 이후 implement functionality and refactor에서 짠다.

- 만약 test할 때 기존에 있는 것은 실패한다면 실패한 단계로 다시 돌아간다.

- 얼만큼 반복할지는 본인의 의지에 따라 결정하면 된다.

 

(2) TDD process activites

- 통상 우리가 짜는 소프트웨어는 작은 것들이다. 이를 개발하고 테스트하는 것을 끊임없이 반복함으로서 소프트웨어를 안정적으로 만들고자 한다.

- 에러가 발생했을 때 구현한다.

- 기존에 짠 것과 새롭게 짠 것이 모두 pass한다면 그 다음 것을 구현한다.


3) test를 함에 따른 이점

(1) Code coverage

모든 specification을 최소 하나 이상 test하니 이러한 테스트의 목적을 만족한다.

 

(2) Regression testing

이전에 짠 것들은 안정적일 가능성이 높기에 에러가 발생할 가능성이 줄어든다

.

(3) Simplified debugging

에러가 발생한다면 지금 짠 것이 에러일 가능성이 높기에 디버깅이 쉽다.

 

(4) System documentation

테스트 코드는 정형화되었기에 문서처럼 사용할 수 있다.

 


4) Regression testing

- 이전에 했던 것에서 에러가 발생한 경우가 나타날 수 있다. 새롭게 짠 것으로 인해 에러가 발생할 수 있는데, 하나하나씩 진행하다보면 문제가 어디서 발생했는지 집중할 수 있다. 또한 테스트 코드는 점차 추가되기에 기존 테스트 코드에서 더 추가하기에 기존 코드에서 오류가 발생하면 그 코드가 뭘 테스트했는지 다시 확인하면서 디버그 시간을 줄일 수 있다. -> 디버그할 대상이 명확해지며 문서화가된다.

 


5) 중요한 철학

- test code를 통과할 수 있을만큼의 코드만 짜라! 쓸데없이 많이 짜지 말고, 테스트 코드를 통과할 수 있을 정도만 짜는 것이 중요하다. 다시 말해 많은 고민은 성능의 저하나 프로그램의 크기를 키울 수 있기에 적절한 크기를 조절하는 것이 중요하다.

 


6) TDD 추천 책

- 테스트 주도 개발

- 클린코드를 기반으로한 테스트 주도 개발

- 임베디드 C를 위한 TDD

- Test-driven IOS development

 


 

3. Release testing

1) 개념

- 소프트웨어가 개발팀을 떠난다.

- 기술진 입장에서의 test 이후에 사용자 입장에서의 test 진행

- block-box testing: 시스템 내부가 모른다는 것을 가정 하에 테스트한다.

 

 information system과 sat과의 인터페이스 테스트

 

- system level의 specification을 했는데, 시스템 레벨의 요구 기능이 갖춰졌는지 테스트한다.

- 이는 시스템 테스팅의 연장선에 포함된다.

- 전용팀이 꾸려지고, 객관적인 시각에서 개발팀에서 개발한 시스템이 고객의 요구사항에 맞는지 확인한다.

 


2) Requirements based testing

(1) 요구사항에 기반해서  테스트한다.

ex) 멘탈 케어 시스템

- 환자가 있을 때 알러지가 있다면 알러지 정보를 warning한다. -> 이를 무시한다면 왜 무시하냐는 근거를 남기는 과정이 필요하다라고 요구사항에서 정의했다면 이를 테스트한다.

 

(2) realease testing은 자동화된 툴보단 사용자처럼 키보드와 마우스를 가지고 유저인터페이스를 보면서 작업하는 경우도 많다.

ex) 멘탈 케어 시스템

- 환자가 알러지가 없는 경우 warning 메세지 x -> 알러지가 없는 것처럼 환자가 인위적인 데이터를 만들어서 집어넣고 확인한다.

- 환자 정보를 미리 만들고, 알러지가 영향을 끼치는 처방을 전달해서 warning 메세지가 뜨는지 확인

- 두개, 혹은 세개 이상의 약에 대해 알러지 반응이 있다면 모든 약에 대해 warning 메세지를 띄운다. 등등

 

- scenario based 처럼 시나리오를 쓸 수 있다.

- 기술적인 관점도 본다. ex) 로그인이 되는지, 업로드 및 다운로드가 되는지, 스케줄링, 암호화, 데이터 읽기 쓰기 등등 체크가 되어야한다.

- 성능(performance) 또한 테스트해서 확인한다.

- 사용자가 증가하면 network 등이 늘어나기에 이를 나눠서 처리해야한다.

- 동시 사용자 1000명은 1001명, 1002명이 들어오면 버려야한다. -> 이때 시스템이 죽으면 안된다.

- Stress testing: 모의 유저를 증가시켜서 부하를 전달했을 때 어떻게 되는지 확인한다.

 


4. User testing

고객이  만족하는지에 대한 테스트


 

1) user testing

- 내/외부 고객이 시스템을 사용해서 개선점을 말해주거나 잘못된 점을 바로잡거나 돈을 줄지 말지 결정하는 과정

- plan based나 waterfall에서도 반드시 이루어지는 과정이다.


2) types of user testing

(1) Alpha testing

- 상용 출시를 앞뒀을 때 외부의 반응을 볼 때 사용한다.

- 선별적인 사용자를 모으고 그들의 반응을 보고 확인한다.

- 돈을 주고 주문하는 부서가 있다면 그 부서를 중심으로 소수의 그룹들이 우리의 개발팀과 밀겹합되어서 테스트를 한다. 우리 시스템이 뭔지 어렴풋이 알지만 우리 개발팀과 밀겹합되어있어서 이를 우리 구획 내에서 개발한다.

-> 어느정도 소프트웨어에 대한 지식이 있는 한정적인 사람들을 대상으로 테스트 진행한다.

- 이것이 잘 되면 베타로 간다.

 

 

(2) Beta testing

- 새로운 사람들에 대해 테스트를 맡겨서 개선점을 얘기하면 업그레이드하고 다시 Beta 테스트를 한다.

- 조금 더 확장적으로 테스트가 가능하다.

 

 

(3) Acceptance testing

- 돈을 주는 사람이 돈을 줄지말지 정하는 것

- 가장 중요한 테스트이다.

- 팀 내부에서도 요구 사항을 다 만족했다고 인정해서 도장을 찍는 단계가 있다.

- 이 단계 이후에는 출시 후 maintanance하는 단계로 넘어간다.

 

Acceptance testing process

- 시스템 요구사항을 쓰는 첫 단계에서 이루어지기에 계약 당시에 Define acceptance criteria는 요구사항 단계에서 정한다.

- acceptance test를 위한 시간, 자원 등에 대한 계획을 세우고, test 환경 구축, 사람을 정하고, 방법론, 장비 등을 구축하고 테스트한다. 결과가 나오면 이를 반영해서 안되는 경우에는 되도록하고, 수치가 논란을 일으킬 경우에는 협상을 해야한다. 즉, 레포트에 따라 accept를 할지말지 결정한다.

- 이후 accept된다면 시장에 출시된다. -> 기술적 백그라운드가 없어도 사용 가능

 

(4) Agile methods and Acceptance testing

- agile인 경우에는 외부 사용자들이 쓰는 것이긴 하지만 소프트웨어를 만들고, 요구사항을 적는 건 내부에서 많이 한다. 이에 따라 acceptance testing을 agile에서 사용하는 것은 애매하지만 필요할수도 있다. User를 대신하는 사람이 회사 내부에 있을수도 있다. Devops에서 소프트웨어 규모가 크면 development와 운영팀은 다를 수 있다. 이에 따라 Acceptance에 대해 결정하는 것은 회사 내부에 있는 사람들이된다. 이에 따라 애매하다.

- operation이 있는 경우에는 Acceptance test와 release testing이 합쳐져있는 경우라고 볼수도 있다.

- agile에 익숙한 회사에서도 알파, 베타 테스트를 할수도 있다.

 


요약

- 작은 소프트웨어를 짜더라도 테스트는 반드시 존재하긴한다. 따라서 이는 의미론적으로 생각하면 좋다. 

- 테스트가 성공적이냐는 테스트를 하는 사람이 얼마나 창의적으로 시스템을 이해하고 테스트하는지에 달려있다. 문제를 찾아가는 것이 테스트의 목적이다. 

- TDD 베이스처럼 개발하면서 테스트하는 것은 조금 더 효율적일 수 있다.

- Development testing이 존재한다.

 - test의 성격에 따라 테스트하는 주체가 달라질 수 있다.

- development testing은 unit testing, component testing, system testing으로 구분할 수 있다.

- 테스트를 할 때는 우리 시스템이 제대로 동작하지 않는 것을 찾아서 방어하는게 중요하다. 시스템을 뭉개버리고 싶은 마음으로 테스트해라.

- 테스트는 자동화해서 할 수 있으면 자동화해라.

- TDD는 테스트코드부터 먼저 쓰고 먼저 테스트한다. -> 반드시 경험하는 것이 중요하다.

- 모든 케이스에 대해 시나리오 베이스드한다. -> 함수 입출력에 맞춰 시나리오를 만들어서 사용한다.

- acceptance test: 유저가 결정을 내린다. 이후에는 릴리즈를 한다.

728x90
반응형