Software Testing

난1렙이요·2024년 12월 13일

소프트웨어 공학

목록 보기
9/12

Program Testing

  • 프로그램이 제대로 작동하는 지 확인하기 위해선 테스트가 필요하다.
  • 테스트는 프로그램이 정확히 작동하는지, 오류가 생기지 않는지, 원하는 방식으로 작동하는지 등을 확인한다.
  • 테스트를 실행할 때, 실제 데이터가 없으므로 가상으로 만들어진 데이터를 이용한다. 잘 만들어진 가상의 데이터를 통해 실제 데이터로 실행하는 것과 같은 역할을 해주며, 버그/에러/falut 등을 찾아낸다.
  • 프로그램 사이즈가 일정 수준 이상 되면 테스트를 잘 만들어도 오류가 생기지 않는다는 보장을 할 수 없다. 테스트는 완벽한 프로그램을 만든다긴 보단 치명적인 오류를 찾아내는 과정이라고 생각해야 한다.
  • 테스팅이라는 용어보단 V&V(verification and validation)이라는 용어가 많이 쓰인다.

V&V

Validation testing

  • 고객의 요구사항을 만족시키는지 확인하기 위한 테스팅이다.
  • 오류를 찾는 테스트가 아니다.
  • “소프트웨어가 고객의 실제 요구사항을 만족하는가?”

Verification testing

  • 성능이나 동작을 확인하기 위한 테스팅이다.
  • 오류를 찾는 테스팅이며, 시스템이 원하는 동작방식으로 동작하는지 확인하는 테스팅이다.
  • “소프트웨어가 요구사항 공학을 통해 나온 내용대로 작동하는가?”

V-Model

  • 제일 작은 단위인 Unit단위로 먼저 테스트한다.
  • Unit단위에서 오류가 없으면 Unit이 여러개 모여서 하나의 기능을 하는 Sybsystem을 테스트한다.
  • Subsystem단위에서 오류가 없으면 전체 시스템을 테스트한다.
  • 만들어진 전체 시스템은 임시 시스템이다. 고객의 요청사항이나 허락을 받아(alpha, beta test) 실제 프로그램을 출시한다.
  • 중간에 고객의 리뷰나 요청을 받아서 각각의 요소들을 수정한다.

V&V confidence

  • V&V의 목표는 "시스템이 목적에 맞는가?"를 확인하는 것이다.
  • 테스팅을 오랜기간 많이 하는 것은 비용과 시간이 많이 들고 불필요한 과정일 수 있다.
  • V&V confidence는 시스템의 보장성으로, 시스템이 문제가 없으며 목적에 맞는지를 말한다.
  • V&V confidence는 다음 요소들로 구성되어 있다.
    • Software purpose : 소프트웨어가 어떻게 작동하며 치명적인 문제가 없어야 한다.
    • User expectations : 고객은 사용하는 소프트웨어에 대해 낮은 이해도를 가지고 있는 경우가 많으므로 예측하지 못한 상황을 대비해야 한다.
    • Marketing environment : 시장의 환경을 잘 고려해야 한다. 경쟁사보다 빠르게 프로그램을 만드는 등이 여기 해당한다.

3+1 Axes of V&V

  • Optimistic Inaccuracy
    • 어느 정도 규모가 있는 프로그램은 잠재적인 오류가 있을 수 밖에 없다.
    • 우리는 프로그램이 오류를 가질 수 있다는 것을 인정해야 한다.
    • 알파 / 베타 테스트를 거쳐도 오류는 계속해서 나오며, 아직 안 나오고 숨어있는 오류들은 무궁무진하므로, 최대한 줄일려는 노력을 해야지 없애려고 하면 힘들다.
    • Example : Testing
  • Pessimistic Inaccuracy
    • 테스팅은 코드와 가상 데이터를 가지고 어떤 일이 일어나는지 예측한다.
    • 프로그램이 실제로는 오류가 없어서 제대로 돌아가는 상황에도 false alarm 때문에 오류가 난다고 할 수 있다.
    • 논리적으로는 문제가 없어도, 실제 상황에 들어가면 성능이나 시간 때문에 오류가 생기는 경우가 많다.
    • 그러므로 실제 테스트를 통해 오류가 일어나는지 확인해야 한다.
    • Example : Automated Program analysis
  • Simplified Properties
    • 모델의 자율성을 낮추어 확인이 간편하도록 해야 한다.
    • Example : Model Checking
  • Review

Software Testing Stages

  • Development testing : 개발 과정 도중에 테스트를 통해 버그와 오류를 찾아낸다.
  • Release testing : 고객에게 배포하기 전에 전문화된 테스트 팀을 통해 시스템의 오류를 찾아낸다.
  • User testing : 고객들에게 오류에 대한 정보를 받아 오류를 찾아내고 고친다.

Development Testing

  • Unit testing
    • 제일 작은 개별의 프로그램인 unit이나 object class를 테스트한다.
    • 유닛 테스팅은 각각의 unit이 맡은 기능을 제대로 수행하는지에 집중한다.
  • Integrated testing
    • unit들이 기능을 수행하는 게 보장되었으면 이들을 합치는 Integrated testing을 수행한다.
    • 개별로 잘 작동한다 해서 합치면 많은 문제가 일어날 수 있으므로 합치는 과정이 중요하다.
  • System testing
    • 위에서 합친 프로그램을 모두 합쳐 하나의 시스템을 만든다.
    • 전체적으로 합쳐서 하나의 시스템을 만드는 것을 목표로 한다.
  • Regression testing
    • 코드를 refactoring하거나 Clean code로 바꾸는 경우에 원래 기능을 똑같이 수행하는지를 확인한다.
    • 유지보수 단계에서 수행한다.

Unit testing

  • Unit testing은 독립적인 요소들을 전체 시스템에서 고립시켜서 테스트하는 것이다.
  • 독립적인 요소(unit)가 기능적으로 잘 작동하는지를 확인한다.
  • unit의 종류는 다음과 같다.
    • 독립적인 함수
    • 변수와 함수를 가진 클래스
    • 여러가지 인터페이스(interface)를 사용하는 컴포넌트
  • Unit testing은 상태도(state model)를 가지고 하는 경우가 많다.

Automated Testing

  • 테스트를 인간이 직접 하는건 너무 복잡하고 어려운 일이다.
  • 그러므로 가능하면, unit testing은 자동화(automated)되어야 한다.
  • 이를 도와주는 것이 Unit testing frameworks다.
    • 일반적인 기능에 대해 테스트 할 수 있다.
    • 특별한 상황(오류)에 대해 테스트할 수 있다.
    • 만든 모든 테스트를 수행하고, 이에 대한 보고를 내며, 성공적으로 수행될 수 있또록 한다.
    • JUnit, xUnit...
  • 3가지 과정으로 나뉜다.
    • Setup part : 맨 처음 하는 과정으로 test case들을 만들고, input과 output을 설정한다.
    • Call part : 함수나 요소를 테스트한다(테스트하도록 부른다).
    • Assertion part : 내가 예상한 결과와 테스트 결과를 비교한다. 만약 둘이 같다면 테스트가 성공적으로 진행된 것이고, 다르면 실패한 것이다.

Developing Unit Test Cases

  • Unit Test Case는 테스트하는 상황에 따라 2가지로 나뉜다.
  • Positive
    • 기능대로 동작하는지를 확인한다.
    • 내가 짠 프로그램이 원하는 방식으로 동작하는지 확인한다.
  • Negative
    • 오류를 잘 처리하는지 확인한다.
    • 예상하지 못한 input이 들어오거나 overflow등 시스템적인 한계를 마주하면 뒤따르는 오류를 잘 처리하는지를 확인한다.

Unit Testing Strategies

  • Partition Testing
    • input들의 모둠을 짓고 그에 따라 테스트를 수행한다.
    • 예를 들어 4~10사이에 있는 수를 구별하는 프로그램이 있으면 다음을 수행해본다.
      • 4보다 작은 수, 4, 4보다 크고 10보다 작은 수, 10, 10보다 큰 수
    • 이는 4보다 작은 수 / 4 ~ 10 / 10보다 큰 수 3가지로 모둠지어 테스트를 수행한 것이다.
  • Guideline-basefd testing
    • 가이드 라인에 따라 테스트를 "잘" 한다.
    • 이 가이드 라인은 프로그램에서 발생하는 주된 오류들이 포함된다.
    • 또한 개발자가 직접 만들면서 발생했던 오류들을 해결하는 가이드 라인이 추가된다.
    • 다시말해, Brute-force testing(막 테스트)하는 것이다.

Integration Testing

  • Integration Tesitng은 Unit Testing이 끝나고 나온 component(unit)들을 서로 병합한다.
  • 이 과정에서 오류가 생길 가능성이 많으므로 잘 작동하는 지를 테스트한다.
  • 컴포넌트들 간에 상호작용하는 것을 중요하게 본다.
  • 컴포넌트들의 기능(interface)들이 합쳐져도 잘 작동하는지를 중요하게 본다.
  • Intergration Testing은 비슷한 기능들끼리 묶어서 하나의 시스템으로 만드는 것이다.
    • 예를 들어 멀티플레이 게임을 만든다 하자.
    • 게임의 전투 부분을 합치고, 설정 부분을 합치고, 멀티플레이 부분을 합치고... 등등 각각의 기능들을 유사한 기능끼리 합친다.

System Testing

  • System testing은 Integration Testing으로 만든 기능들을 하나로 합쳐서 최종 시스템을 만든다.
    • 기능들을 합치는 과정을 중요하게 본다.
  • 이미 만들어진 기능을 다시 확인하는 것은 하지 않는다. 왜냐하면 Unit test, Integrating test에서 기능이 보장되어야만 System testing으로 오기 때문이다.
  • 그렇기에 각각의 부분이 어떻게 작동하는지는 중요하지 않으며, input을 넣었을 때 원하는 output이 나오는 것만 본다.
  • 이들을 병합하는 것은 쉬울수도 있고, 어려울 수도 있다.
    • 어떤 시스템은 각각의 기능들이 연결 부분이 많이 없어 로봇의 각 부분처럼 붙이기만 하면 된다.
    • 혹은 어떤 시스템은 기능끼리 소통하는 부분이 많아 로봇의 전선을 연결하고 납땜질을 해야할 수 있다.

Regression Testing

  • 코드는 오류 수정이나 성능 향상을 위해서 변경될 때가 있다.
  • 코드가 변경되면, 이에 영향을 받는 모든 주변 기능은 작동이 달라질 수 있다.
    • 어떤 코드가 변경되도 영향을 받지 않는다.
    • 어떤 코드가 변경되면 영향을 받지만, 똑같이 동작한다.
    • 어떤 코드가 변경되면, 동작이 달라진다.
  • 이에 따라 코드가 변경되면 주변 기능이 동일하게 작동하는지 테스트해야 한다. 이를 Regression Testing이라고 한다.
  • Regression Testing은 비용이 비싸지만, 자동화된 시스템을 사용하기 때문에 간단하다.
    • Regression Testing의 비용이 비싸므로, 범위를 정해서 테스트하는 방법이 있다. 비용을 줄일 수 있지만, 범위가 축소되므로 확실하지 않을 수 있다.

Test-Driven Development

  • Test-Driven Development(TDD)는 개발을 어떻게 해야 할 지 알려주는 개발 방법론이다.
  • 지금까지는 코드(Unit)를 먼저 만들고 테스트를 통과할 때 까지 고쳤다.
  • TDD는 코드를 구현하기 전 Test Case를 먼저 만드는 개발 방법이다.
  • 아무것도 없는데 Test Case를 먼저 만드는 것은 힘드므로, Specification에 대한 이해도가 높아야 하며 코드에 대한 대략적인 구상을 해야한다.
  • TDD가 된다고 TFD가 되는 건 아니다.
  • TDD를 사용함으로써 얻는 이득은 다음과 같다,
    • 모든 작성될 코드는 작성한 테스트를 통과해야 하므로 모든 코드가 적어도 하나의 테스트를 통과하게 된다.
    • 테스트를 기반으로 코딩했으므로 Test 자동화가 쉽게 완료되며 이에 따르는 Regression Testing이 쉬워진다.
    • 코드를 짜면 바로 테스트를 하기 때문에 Debugging하는 것이 쉬워진다.
    • 코드가 무엇을 해야하는지를 테스트로 구현해놓았기 때문에 문서로 작성하기 쉽다.

Release Testing

  • Release Testing은 사용자에게 직접 주기 전에 해보는 Testing을 의미한다.
  • 대부분 Testing Team이 있으며, 그만큼 Release Testing은 중요하다.
  • Black-box Testing은 사용자가 직접 사용할 기능들을 가지고 안에 구조는 보지 않은채 테스트를 한다.
  • White-box Testing은 구조를 파악하고 구조에 맞는 테스트를 한다.
  • 대부분 Black-box Testing을 많이 하는데, 구조를 몰라도 되며 사용자가 할 만한 행동들이 대부분이므로 사용자 친화적인 Testing이기도 하다. 그렇기에 negative testing과도 비슷한 부분이 있다.

Release Testing vs. System Testing

  • Release Testing은 System Testing의 종류 중 하나이다.
    • Systme Testing은 개발 팀에서 구조를 보면서 버그를 찾아내기 위함이다.
    • Release Testing은 어떤 상황에도 대응이 되어야 하며, 사용자가 사용하기 좋아야 함을 기반으로 한다.
  • Release Testing은 성능 테스트나 스트레스 테스트를 진행한다.
    • 성능 테스트는 시스템이 요구하는 최소 성능을 확인하는 것이며, 최소 성능이 높으면 범용성이 떨어지므로 최소 성능을 낮추어야 한다.
    • 스트레스 테스트는 시스템이 사용자에게 좋지 않는 경험을 주는 것으로, 버퍼링이나 렉 같은 요소들이 해당된다. 이는 사용자 경험에 좋지 않은 영향을 주므로 빠르게 개선해야한다.

User Testing

  • User / Customer testing은 시스템을 필요한 사용자에게 제공하며 테스트해보는 것이다.
  • 개발자나 테스트 팀이 아닌 실제 사용자의 테스트이므로, 여러 환경이나 요소들에 대한 정보를 수집할 수 있으므로 도움이 된다.
  • 또한 사용자 PC나 여러 환경들에 설치되어 있는 프로그램과의 충돌들도 발견해 낼 수 있어 여러모로 이점이 있다.
  • 인터넷 기반의 시스템이 User Testing을 많이 한다.
  • User Testing의 종류는 다음과 같다.
    • Alpha Testing : 유저가 개발자의 site(인터넷 사이트나, 개발자의 개발 환경, 테스트벤치 등...)에 접속해서 테스트한다.
    • Beta Testing : 시스템을 발매하고 유저가 직접 받아서 자신의 환경에서 테스트한다.
    • Acceptance Testing :
profile
다크 모드의 노예

0개의 댓글