/////
Search

221013

작성자
최민준
조예지
날짜
2022/10/13
학습 내용
TDD,정렬
텍스트

TDD - 최민준

정의

테스트 주도 개발(Test-driven development TDD)의 약자.
Test Driven Development의 약자. 테스트 코드를 먼저 만들고 잘 작동되는지 확인 후에 또 다시 덧붙이고 덧붙이는 방법이다.
• System.out.println()으로 하는 번거로운 디버깅이 필요없으며, 개발기간 중 대부분을 차지하는 디버깅 시간을 단축

Red, Green, Refactoring

Red : 하려는 행위를 변수, 객체, 메소드가 있다는 전제하에 코드를 작성한다. 테스트를 실행하고 실패한다.
Green : 테스트를 통과시키기 위한 코드를 작성한다.
Refactoring : 통과된 코드를 리팩토링한다.
최근 개발 트렌드는 test를 적극 활용해서 개발한다.
자바에서는 TDD에 위해 JUnit을 사용한다.

JUnit

정의

자바 프로그래밍 언어용 유닛 테스트 프레임워크
어노테이션으로 간결하게 지원(JUnit4부터)
단정(assert) 메서드로 테스트 케이스의 수행 결과를 판별

사용 방법

build.gradle dependencies에 junit 의존성을 추가한다
테스트 케이스를 만들고 싶은 클래스, 메서드에 Ctrl+Shift+T 를 해서 Test 클래스 작성

assert 메서드

assertArrayEquals(a, b)

int[] arr = new int[]{1, 2, 3}; @Test void Check() { assertArrayEquals(new int[]{1, 2, 3},arr); }
Java
복사
배열 A와 B가 일치함을 확인

assertEquals(a, b)

@Test void Check() { String str = "Hello World!"; assertEquals("Hello World!", "Hello World!"); }
Java
복사
객체 A와 B가 같은 값을 가지는지 확인

assertEquals(a, b, c)

//test 실패 코드 double numA = 1.5; @Test void Check() { assertEquals(1.3, numA, 0.1); } //출력 expected: <1.3> but was: <1.5> Expected :1.3 Actual :1.5
Java
복사
객체 A와 B가 값이 일치함을 확인( a: 예상값, b:결과값, c: 오차범위)

assertSame(a, b)

//test 실패 코드 String str1 = new String("1234"); String str2 = new String("1234"); @Test void Check() { assertSame(str1,str2); } //출력 expected: java.lang.String@17916787<1234> but was: java.lang.String@4726fe5e<1234> org.opentest4j.AssertionFailedError: expected: java.lang.String@17916787<1234> but was: java.lang.String@4726fe5e<1234>
Java
복사
객체 A와 B가 같은 객체임을 확인

assertTrue(a)

@Test void Check() { assertTrue(3<1); } // 출력 org.opentest4j.AssertionFailedError: Expected :true Actual :false
Java
복사
조건 A가 참인지 확인

assertNotNull(a)

String str = "Hello World!"; @Test void Check() { assertNotNull(str); }
Java
복사
객체 A가 null이 아님을 확인

어노테이션 종류

@Test

테스트 메소드를 나타내는 어노테이션입니다. 필수로 작성

@DisplayName

테스트 클래스 또는 테스트 메서드의 사용자 정의 표시 이름을 정의

@ExtendWith

사용자 정의 확장명을 등록하는데 사용

@BeforeEach

각 테스트 메소드 시작 전에 실행되어야 하는 메소드에 작성

@AfterEach:

각 테스트 메소드 종료 후에 실행되어야 하는 메소드에 작성

@BeforeAll

테스트 시작 전에 실행되어야 하는 메소드에 작성

@AfterAll

테스트 종료 후에 실행되어야 하는 메소드에 작성

@Disable

실행되지 않아야 하는 테스트 메소드에서 작성

버블삽입정렬, Gradle, Annotation, TDD - 조예지

○ 버블삽입정렬

칠판 코딩 가능할 정도로 알아야 한다
[필요한 기술]
1.
swap 자리바꾸기
2.
중첩 for ans
3.
중첩 for 문 control
정렬 아이디어
1.
처음의 수와 오른쪽에 위치한 수들을 하나씩 비교하면서 더 작은 수와는 swap을 하고 아니면 지나간다.
a.
1 라운드가 지나면 첫 칸에는 배열에서 가장 작은 수가 오게 된다.
2.
두번째 수도 오른쪽 수들과 비교를 한다.
a.
두번째 칸에는 배열에서 두번째 작은 수가 오게 된다.
(….반복)
3.
마지막 전칸까지 반복한다.
[코드 작성 요건]
static method는 main method에만 사용하기
int[] 를 받고 int[]를 반환하는 메서드
[구현 방법]
첫번째 수와 나머지 오른쪽 수들을 비교하면서 더 작은 수를 첫번째 칸에 넣는 코드를 만들어 본다.
한 칸씩 옆으로 이동하는 것을 구현해본다.
 코드
Gradle 쓰는 이유?
test case를 작성하고 실행하기 좋다.
 Gradle

○ Test code

@Test : 테스트 코드임을 알려준다.
 스프링과 어노테이션

 Unit test:

gradle - tasks - verification에서 단위 테스트를 할 수 있음

 integration test

: 배포하기 전에 실행
gradle에 build를 하게되면 테스트가 돌아간다. build 실행.
gradle build할 때 실행 되는 작업들
Task :test 에서 지금까지 만들었던 모든 테스트 코드를 실행 한다.
테스트를 통과하면 jar 파일이 만들어지고, jar 파일을 서버에 올리면 어플리케이션이 구동된다.

○ TDD (Test Driven Development) - 테스트 주도 개발

TDD란 반복 테스트를 이용한 소프트웨어 방법론으로, 작은 단위의 테스트 케이스 (단위 테스트)를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여 구현한다.
짧은 개발 주기의 반복에 의존하는 개발 프로세스이며 애자일 방법론 중 하나인 eXtream Programming (XP)의 ‘Test-First’ 개념에 기반을 두었다.

TDD 장점

 일반 개발 방식의 문제점
보다 튼튼한 객체 지향적인 코드 생산
TDD는 코드의 재사용 보장을 명시하므로 TDD를 통한 소프트웨어 개발 시 기능 별 철저한 모듈화가 이뤄진다. 이는 종속성과 의존성이 낮은 모듈로 조합된 소프트웨어 개발을 가능하게 하며 필요에 따라 모듈을 추가하거나 제거해도 소프트웨어 전체 구조에 영향을 미치지 않게 된다.
재설계 시간의 단축
테스트 코드를 먼저 작성하기 때문에 개발자가 지금 무엇을 해야하는지 분명히 정의하고 개발을 시작하게 된다. 또한 테스트 시나리오를 작성하면서 다양한 예외사항에 대해 생각해볼 수 있다. 이는 개발 진행 중 소프트웨어의 전반적인 설계가 변경되는 일을 방지할 수 있다.
디버깅 시간의 단축
이는 유닛 테스팅을 하는 이점이기도 하다. 예를 들면 사용자의 데이터가 잘못 나온다면 DB의 문제인지, 비즈니스 레이어의 문제인지 UI의 문제인지 실제 모든 레이러들을 전부 디버깅 해야하지만, TDD의 경우 자동화 된 유닛테스팅을 전재하므로 특정 버그를 손 쉽게 찾아낼 수 있다.
테스트 문서의 대체 가능
주로 SI 프로젝트 진행 과정에서 어떤 요소들이 테스트 되었는지 테스트 정의서를 만든다. 이것은 단순 통합 테스트 문서에 지나지 않는다. 하지만 TDD를 하게 될 경우 테스팅을 자동화 시킴과 동시에 보다 정확한 테스트 근거를 산출할 수 있다.
추가 구현의 용이함
개발이 완료된 소프트웨어에 어떤 기능을 추가할 때 가장 우려되는 점은 해당 기능이 기존 코드에 어떤 영향을 미칠지 알지 못한다는 것이다. 하지만 TDD의 경우 자동화된 유닛 테스팅을 전제하므로 테스트 기간을 획기적으로 단축시킬 수 있다.

TDD 방법 및 순서

1.
실패하는 작은 단위 테스트를 작성한다. 처음에는 컴파일조차 되지 않을 수 있다.
2.
테스트를 통과하기 위해 프로덕션 코드를 작성한다. 이를 위해 정답이 아닌 가짜 구현 등을 작성할 수도 있다.
3.
그 다음의 테스트 코드를 작성한다. 실패 테스트가 없을 경우에만 성공 테스트를 작성한다.
4.
새로운 테스트를 통과하기 위해 프로덕션 코드를 추가 또는 수정한다.
5.
1~4단계를 반복하여 실패/성공의 모든 테스트 케이스를 작성한다.
6.
개발된 코드들에 대해 모든 중복을 제거하며 리팩토링한다.
위의 그림은 TDD의 개발주기를 표현한 것이다. <Red> 단계에서는 실패하는 테스트 코드를 먼저 작성한다. <Green> 단계에서는 테스트 코드를 성공시키기 위한 실제 코드를 작성한다. <Yellow> 단계에서는 중복 코드 제거, 일반화 등의리팩토링을 수행한다. 
중요한 것은 실패하는 테스트 코드를 작성할 때까지 실제 코드를 작성하지 않는 것과, 실패하는 테스트를 통과할 정도의 최소 실제 코드를 작성해야 하는 것이다. 이를 통해, 실제 코드에 대해 기대되는 바를 보다 명확하게 정의함으로써 불필요한 설계를 피할 수 있고, 정확한 요구 사항에 집중할 수 있다.

단위 테스트를 작성하는 이유

코드를 수정하거나 기능을 추가할 때 수시로 빠르게 검증 할 수 있다.
리팩토링 시에 안정성을 확보할 수 있다.
개발 및 테스팅에 대한 시간과 비용을 절감할 수 있다.

좋은 테스트 특징 (FIRST)

1.
Fast: 테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다.
2.
Independent: 각각의 테스트는 독립적이며 서로 의존해서는 안된다.
3.
Repeatable: 어느 환경에서도 반복 가능해야 한다.
4.
Self-Validating: 테스트는 성공 또는 실패로 bool 값으로 결과를 내어 자체적으로 검증되어야 한다.
5.
Timely: 테스트는 적시에 즉, 테스트하려는 실제 코드를 구현하기 직전에 구현해야 한다.

정렬 알고리즘,TDD - 정희준

정렬 알고리즘 (Sort Algorithm)

정렬 알고리즘은 n개의 데이터가 입력으로 들어오게 되면 사용자가 원하는 기준으로 정렬해주는 알고리즘 입니다. 일반적으로 내림차순,오름차순으로 정렬을 하여 답을 얻게 됩니다.

선택정렬 (Selection Sort)

선택 정렬은 현재 자리에 들어갈 데이터를 찾아 정렬하는 방법 입니다.선택 정렬에서는 최소 선택 정렬,최대 선택 정렬이 있는데 최소 선택 정렬은 오름차순으로 정렬하는 방법이고 최대 선택 정렬은 내림차순으로 정렬하는 방법 입니다.오름차순으로 선택 정렬을 진행 해 보겠습니다. 배열에 여러개의 데이터가 저장되어 있다고 가정 합니다.1. 정렬되지 않은 배열을 비교하여 가장 작은 값을 찾아 갑니다.2. 찾은 가장 작은 값을 정렬 되지 않은 배열의 맨 앞에 있는 원소와 교환 합니다.3.위의 1,2번 과정을 반복 합니다.
public int[] sSort(int[] arr){ for (int i = 0; i <arr.length-1; i++){ // 정렬되지 않은 배열중 비교 후 가장 작은 값과 비교될 인덱스 int minIndex = i; for (int j = i+1; j < arr.length; j++){ // 배열 인덱스를 전부 비교 if (arr[minIndex] > arr[j]){ minIndex = j; // 인덱스 값 저장 } } int a = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = a; }return arr; }
Java
복사
import java.util.Arrays; public class SelectionSortMain { public static void main(String[] args) { int[] arr = new int[]{7, 2, 3, 9, 28, 11}; SelectionSort selectionSort = new SelectionSort(); System.out.println(Arrays.toString(selectionSort.sSort(arr))); } }
Java
복사
선택 정렬 알고리즘 코드 입니다.

버블 정렬

두개의 인접한 원소를 비교하여 정렬해주는 방식 입니다. 좀 더 자세히 설명하자면 오름차순으로 정렬 한다고 가정 하겠습니다.1. 가장 첫번째 원소와 인접한 두번째 원소와 비교 해 줍니다. 첫번째 원소가 크다면 두 원소의 위치를 변경 해 줍니다. 그렇지 않다면 그대로 둡니다.2. 다음 번째 원소와 인접한 원소를 1번 과정과 같이 비교 후 변경 해 줍니다.3. 1,2번 과정을 마지막 원소까지 비교 후 다시 첫번째 원소로 와서 이 과정을 원소의 개수에 한번 적은 만큼 반복 해 줍니다.
public int[] bSort(int[] arr){ for (int i = 0; i <arr.length-1; i++){ // 정렬되지 않은 배열중 비교 후 가장 작은 값과 비교될 인덱스 for (int j = i+1; j < arr.length; j++){ // 배열 인덱스를 전부 비교 if (arr[i] > arr[j]){ int a = arr[i]; arr[i] = arr[j]; arr[j] = a; } } }return arr; }
Java
복사
import java.util.Arrays; public class BubbleSortMain { public static void main(String[] args) { int[] arr = new int[]{7,2,3,9,28,11}; BubbleSort bubbleSort = new BubbleSort(); System.out.println(Arrays.toString(bubbleSort.bSort(arr))); } }
Java
복사
버블 정렬 알고리즘 코드 입니다.

TDD란?

수업에서 TDD 라는 것을 배웠다. 그럼 TDD란 뭘까?위키백과에서 찾아 보았다.테스트 주도 개발(Test-driven development)는 짧은 개발 사이클을 반복하는 소프트웨어 개발 프로세스이다. 개발자는 원하는 결과를 검증하는 테스트 케이스를 작성한다. 그리고 그 테스트 케이스를 통과할수 있는 간단한 테스트 코드를 작성한다. 마지막으로 작성한 코드를 표준에 맞게 리팩토링한다.
사실 글을 읽어보면 무슨 의미인지는 알겠지만 크게 와닿지는 않을 수 있습니다.쉽게 말하면 테스트 주도 개발은 개발 과정에 있어 테스트가 주가 되어야 된다는 말 입니다.
기존의 일반적인 사람들은 TDD 를 알기전에 아래의 방식으로 개발을 진행 했을 겁니다.
프로그램 설계 개발 테스트
테스트에서 문제가 생기면 다시 설계로 돌아가 수정을 한 후 이 과정을 반복 하셨을 겁니다.
TDD를 배운 우리는 이제 아래의 방법으로 개발을 할 수 있습니다.
프로그램 설계 테스트 개발
프로그램 설계를 하고 테스트를 진행 후 다시 설계를 수정하는 방법으로 설계 오류를 개선하는 속도가 이전의 방법보다 훨씬 빨라집니다.
위의 장점을 말고도 우리가 TDD가 필요한지 더 확신을 가지기 위해 TDD의 장점에 대해서 알아보겠습니다.

TDD의 장점

1.
객체지향적인 코드 개발 테스트 코드를 작성하면 더 명확한 기능과 구조를 가진 프로그램을 작성 할 수 있습니다. 테스트의 용이성을 위해서 복잡한 기능을 한 함수에 모두 구현할 경우 테스트 방식이 복잡해지고 오래걸리며 코드 수정을 조금이라도 하는 경우 테스트 코드를 사용할 수 없기 때문에 각각의 함수를 정의할때 각각의 기능들을 철저히 구조화 시켜 코드를 작성하게 되며 자연스럽게 코드의 재사용성을 보장하게 됩니다.
2.
설계 수정 시간의 단축. 위에서 설명 하였듯이 테스트 코드를 먼저 작성하기 때문에 입출력 구조와 기능을 명확히 하게 되므로 설계의 오류를 빠르게 찾아 낼 수 있습니다. 그리고 미리 테스트 코드를 작성함으로써 예외 상황을 먼저 확인 해 보며 개발을 더 효율적으로 진행 할 수 있습니다.
3.
디버깅 시간의 단축. 단위 테스트 기반의 테스트 코드가 작성되기 때문에 후에 문제가 생기면 코드 전체를 볼 필요 없이 각각의 모듈별로 테스트를 진행하여 문제점을 빠르게 찾아 시간을 단축 할 수 있습니다.
4.
유지 보수의 용이성. 개발자들은 개발할때 기술적 관점에서 보기 때문에 코드가 복잡해질 가능성이 높습니다.하지만 TDD를 사용한다면 사용자 관점으로 개발이 진행 되기 때문에 입출력의 흐름이 명확해져 추후에 구조 변경이나 소스 수정이 수월해 집니다.
5.
테스트 문서의 대체 가능  일반적으로 개발 후 진행하면 내부적으로 어떻게 테스트가 진행 되었는지 알 수가 없습니다. 하지만 TDD를 진행하면 각각의 테스트를 진행하기 때문에 정확하게 어떻게 테스트가 진행 되었는지 산출 할 수 있습니다.

테스트 진행 방법

1.
구현할려는 기능을 생각한다.
2.
모든 변수와 객체,메서드가 있다는 전제 하에 코드를 작성 합니다.
3.
테스트를 수행 합니다. 테스트를 실패 합니다.
4.
테스트에 통과할 코드를 작성 합니다.
5.
테스트를 통과 합니다.
6.
통과된 코드를 리팩토링을 수행 합니다.

Junit

자바의 TDD 를 담당하는 기술이며, 자바 프로그램의 단위 테스트를 위한 프레임 워크이다.
"@Test"메소드가 호출될 때마다 새로운 인스턴스를 생성하여 독립적 테스트를 수행한다.
assert 메소드로 테스트 케이스의 수행 결과를 판단 합니다.
어노테이션을 제공하여 매우 쉽고 간결하게 테스트 코드를 작성하여 실행 가능하다.
어노테이션을 Junit4부터 간결하게 지원하며 현재는 Junit5가 최신 입니다.

어노테이션 종류 사전적 의미는 주석이라는 뜻!

@Test
해당 메소드가 테스트 대상 메소드임을 의미
@Test(timeout=10)
테스트 메소드 수행 시간이 10 millisecond를 넘기면 실패
@Test(expected=RuntimeException.class)
RuntimeException이 발생하면 테스트 성공, 아니면 실패
@Before
각 테스트 메소드에서 공통적으로 실행해야 할 작업 포함, 테스트 메소드가 실행되기 전에 실행 됩니다.
@After
각 테스트 메소드의 실행이 완료된 후에 동일한 마무리 작업을 수행할 경우 사용, 테스트 메소드가 실행된 후에 실행 됩니다.
@BeforeClass
static 메소드이며, 모든 테스트 메소드가 동작하기 전 공통적으로 실행해야 하는 작업 수행 됩니다.
@AfterClass
static 메소드이며, 모든 테스트 메소드가 생행되고 난 후에 한번 실행하는 메소드 입니다.
@DisplayName
테스트 클래스 또는 테스트 메서드의 사용자 정의 표시 이름을 정의 합니다.
@ExtendWith
사용자 정의 확장명을 등록하는데 사용 합니다.
@BeforeEach
각 테스트 메서드 전에 실행됨을 나타냅니다.
@AfterEach
각 테스트 메서드 후에 실행됨을 나타냅니다.
@BeforeAll
현재 클래스의 모든 테스트 메서드 전에 실행됨을 나타냅니다.
@AfterAll
현재 클래스의 모든 테스트 메서드 후에 실행됨을 나타냅니다.
@Disable
테스트 클래스 또는 메서드를 비활성화 합니다.

Assert 구문

Assert 구문은 확인을 수행하는 동작 입니다.Assert가 제공하는 함수
assertNotNull(a) : 객체 A가 null이 아님을 확인 합니다.
assertArrayEquals(a, b) : 배열 A와 B가 일치함을 확인 합니다.
assertEquals(a, b): 객체 A와 B가 같은 값을 가지는지 확인 합니다.
assertEquals(a, b, c): 객체 A와 B가 값이 일치함을 확인 합니다. ( a: 예상값, b:결과값, c: 오차범위)
assertSame(a, b): 객체 A와 B가 같은 객체임을 확인 합니다.
assertTrue(a): 조건 A가 참인지 확인 합니다.
참고 :