๐ค ์ค์ค๋ก ๊ณต๋ถํ์
๋๋์ด ์นด์นด์ค์บ ํผ์ค 2๋จ๊ณ๊ฐ ๋๋๊ณ ๋ฐฐํฌ๊น์ง ๋๋ด๊ณ ๋๋, ๋๋์ด ๋ด๊ฐ ์น ์ฌ์ดํธ๋ฅผ ๋ง๋ค์๋ค๋ ๋ฟ๋ฏํจ๊ณผ ์ ์ ์ด ์ ์๋ค๋ ํ๋ณตํจ์ ๋๊ผ๋ค. ํนํ 1๋จ๊ณ๋ฅผ ๋๋ธ ๋ค ํด๋ก ์ฝ๋ฉ์ ์ง์ ๋์ ํด ๋ณธ 2๋จ๊ณ์์๋ ๋๋ผ๊ณ ๋ฐฐ์ด๊ฒ ์ ๋ง ๋ง์ ๊ฒ ๊ฐ์๋ฐ ๊ทธ ์ค์์๋ 6์ฃผ ๋ด๋ด ๊ณผ์ ๋ฅผ ์ดํดํ์ง ๋ชปํ๊ณ ๋๋ด๊ธฐ์๋ง ๊ธ๊ธํ๋ ๋๋ฅผ ๋ง์ด ๋๋์ ๋ณด๊ณ ์ค์ค๋ก ๊ณต๋ถ๋ฅผ ์ ๋ง ๊พธ์คํ ํด์ผ๊ฒ ๋ค๋ ๊ฒ๋ ๋๋ ์ ์์๋ค.
๊ทธ๋ฆฌ๊ณ 2๋จ๊ณ๊ฐ ๋๋๊ณ ๋ ๋ค์๋ ์นด์นด์คํ ํฌ ์บ ํผ์ค์์ ์ ๊ณตํด์ฃผ๋ ๊ฐ์๋ค์ ํํฌ๋ก ๋ญ๋นํ์ง ์๊ณ ์น๊ฐ๋ฐ ๊ฒฝํ์ ์๋ ํ ๋๋ก ํ์ฉํด์ผ ๊ฒ ๋ค๋ ์๊ฐ๋ ํ๊ฒ ๋์๋ค. ์นดํ ์ผ์ ์ฐธ์ฌํ๋ฉฐ ๋ ์๋กญ๊ณ ์ฆ๊ฑฐ์ ์ง๋ง ๋ชจ๋ฅด๋ ๋ถ๋ถ๊ณผ ์์๋ค์ ์ ์๋ ๊ฐ์๋ฅผ ๋ง์ฃผํ ๋ ์ ๋ง ํ๋ค์๋ ๊ธฐ์ต์ด ์์ด์ 3๋จ๊ณ ์์ ์ ์กฐ๊ธ์ด๋๋ง ๊ณต๋ถ๋ฅผ ํด๋ณด๊ธฐ ์ํ ์๊ฐ์ ๋ณด๋ด๋ ค๊ณ ํ๋ค.
์นด์นด์คํ ํฌ ์บ ํผ์ค์์ ์ ๊ณตํด์ฃผ๋ ๊ฐ์๋ค ์ค์์ ํจ์คํธ ์บ ํผ์ค์ "10๊ฐ ํ๋ก์ ํธ๋ก ์์ฑํ๋ ๋ฐฑ์๋ ์น๊ฐ๋ฐ"์ ์๊ฐํ๋ฉฐ ๊ทธ๋ก ์ธํด ๋ฐฐ์ฐ๋ ๊ฒ๋ค๊ณผ ํด๊ฒฐํด๋๊ฐ๋ ๊ณผ์ ๋ฑ์ ์ผ์ง๋ก ์ ์ด๋๊ฐ ๊ฒ์ด๋ค.
docker ํ๊ฒฝ ๊ตฌ์ฑ
๐ ๋์ปค ๋ช ๋ น์ด ์ค ์์๋๋ฉด ์ข์ ๋ช ๋ น์ด
- ํ์ฌ ์คํ์ค์ธ ๋์ปค ์ปจํ ์ด๋ ๋ชฉ๋ก ์ถ๋ ฅ : docker ps -a
- ๋์ปค ์ปจํ ์ด๋ ์ญ์ ๋ช ๋ น : docker rm [์ปจํ ์ด๋ID ๋๋ ์ปจํ ์ด๋๋ช ]
ํฌํธ ์ถฉ๋ ๋ฌธ์ ํด๊ฒฐ
docker: Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:3306 -> 0.0.0.0:0: listen tcp 0.0.0.0:3306: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
์์ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์๋๋ฐ, ๋ค์๊ณผ ๊ฐ์ด ํด๊ฒฐํ ์ ์๋ค.
1. ํฌํธ๊ฐ ์ค๋ณต๋๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ ๋ฌธ์ ๋ก, ์ฌ์ฉ์ค์ธ ํฌํธ ์ญ์ ํด์ค๋ค.
cmd๋ฅผ ํตํด netstat -ano | findstr :3306 ๋ช ๋ น์ด ์ ๋ ฅ ํ ํฌํธ๊ฐ ์ฌ์ฉ์ค์ธ์ง ํ์ธ
2. ์ฌ์ฉ์ค์ธ pid ๋ฐ name์ ํ์ธํ๊ณ ์ญ์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํด์ค๋ค. (cmd๋ฅผ ๊ด๋ฆฌ์ ๋ชจ๋๋ก ์คํ !!)
taskkill /f /pid 6016 ์ซ์๋ ๋ณธ์ธ์ ํฌํธ์ ๊ฒน์น๋ pid๋ฅผ ์ ์ด์ค๋ค.
3. ๋์ปค๋ฅผ ์ฌ์์ํ๋ค.
ํ ์คํธ ์ฝ๋
์นดํ ์ผ 2๋จ๊ณ๋ฅผ ์งํํ๋ฉฐ ํ ์คํธ ์ฝ๋์ ์ค์์ฑ์ ์ ๋ง ๋ผ์ ๋ฆฌ๊ฒ ๋๋ ์ ์์๋ค. ์ข์ ํ ์คํธ ์ฝ๋๋ ์น์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ์ฑ ๋ฐ ์์ฑ๋๋ฅผ ๋์ฌ์ฃผ๊ณ ๊ฐ๋ฐ์ ํจ์จ์ฑ์ ๋ณด์ฅํด์ฃผ๋ ๋ฑ์ ๋ง์ ์ญํ ์ ํ๋ค๋ ๊ฒ์ ๋ชธ์ ์๊ฒ ๋์๋ค. ์ด๋ฌํ ํ ์คํธ ์ฝ๋์ ์ข ๋ฅ๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ๋ค์ด ์๋ค.
1. ํ ์คํธ ์ฝ๋์ ์ข ๋ฅ
1) TDD
- Test Driven Development : ํ ์คํธ ์ฃผ๋ ๊ฐ๋ฐ
- ์ ํ ์คํธ ํ ๊ฐ๋ฐ ๋ฐฉ์์ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ๋ฒ
- TFD + ๋ฆฌํฉํ ๋ง
- ๋ฉ์๋ ๋จ์๋ก ๊ธฐ๋ฅ ๋์์ ๊ฒ์ฆ
์ฐธ๊ณ ํ ๋งํ ์ฌ์ดํธ : http://www.incodom.kr/%ED%85%8C%EC%8A%A4%ED%8A%B8_%EC%A3%BC%EB%8F%84_%EA%B0%9C%EB%B0%9C#h_8f3e1ac4f2c1d58852261dff5bb8955a
์๋ฌผ์ ๋ณด ์ ๋ฌธ์ํค, ์ธ์ฝ๋ค
Wikipedia for Bioinformatics
www.incodom.kr
2) BDD
- Behavior Driven Development : ํ์ ์ฃผ๋ ๊ฐ๋ฐ
- ์๋๋ฆฌ์ค ๊ธฐ๋ฐ์ผ๋ก ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฐ๋ฐ ๋ฐฉ๋ฒ
- ํ ์คํธ ์ผ์ด์ค ์์ฒด๊ฐ ์๊ตฌ์ฌ์์ด ๋๋๋ก ํ๋ ๊ฐ๋ฐ ๋ฐฉ๋ฒ
- Given, When, Then ๊ตฌ์กฐ
2. ํ ์คํธ ์ฝ๋ ์ค์ต
์๊ตฌ์ฌํญ
• ๋น๋ฐ๋ฒํธ๋ ์ต์ 8์ ์ด์ 12์ ์ดํ์ฌ์ผ ํ๋ค.
• ๋น๋ฐ๋ฒํธ๊ฐ 8์ ๋ฏธ๋ง ๋๋ 12์ ์ด๊ณผ์ธ ๊ฒฝ์ฐ IllegalArgumentException ์์ธ๋ฅผ ๋ฐ์ ์ํจ๋ค.
• ๊ฒฝ๊ณ์กฐ๊ฑด์ ๋ํด ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํด์ผ ํ๋ค.
TDD ๊ฐ๋ฐ
package org.example;
/*
์๊ตฌ์ฌํญ
* ๋น๋ฐ๋ฒํธ๋ ์ต์ 8์ ์ด์ 12์ ์ดํ์ฌ์ผ ํ๋ค.
* ๋น๋ฐ๋ฒํธ๊ฐ 8์ ๋ฏธ๋ง ๋๋ 12์ ์ด๊ณผ์ธ ๊ฒฝ์ฐ IllegalArgumentException ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค.
* ๊ฒฝ๊ณ์กฐ๊ฑด์ ๋ํด ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํด์ผ ํ๋ค.
*/
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
public class PasswordValidatorTest {
@DisplayName("๋น๋ฐ๋ฒํธ๊ฐ ์ต์ 8์ ์ด์, 12์ ์ดํ๋ฉด ์์ธ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.")
@Test
void validatePasswordTest() {
assertThatCode(() -> PasswordValidator.validate("serverwizard"))
.doesNotThrowAnyException();
}
}
์์ ์ฝ๋๋ assertThatCode๋ฅผ ํตํด PasswordValidator ํด๋์ค ๋ด์ validate ๋ฉ์๋์ "serverwizard"๋ฅผ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌํ ๊ฒฐ๊ณผ exception์ด ๋ฐ์ํ์ง ์์ผ๋ฉด ํ ์คํธ๋ฅผ ํต๊ณผํ๋ ์ฝ๋์ด๋ค.
์ ์ผ ๋จผ์ , main ํจํค์ง์ ์๋ฌด ํด๋์ค๋ ๋ง๋ค์ง ์์ ์ํ์์ ๋ค์๊ณผ ๊ฐ์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ค. ๊ทธ๋ ๊ฒ ๋๋ฉด ๋น์ฐํ test error๊ฐ ๋ฐ์ํ๋ค. (์๋ ํด๋์ค, ์๋ ๋ฉ์๋๋ฅผ ํ ์คํธํ๊ธฐ ๋๋ฌธ์) ์ด๋ TDD ๊ณผ์ ์ค write a failing test์ ํด๋นํ๊ณ ์ด๋ฅผ make the test pass ํด์ฃผ์ด์ผ ํ๋ค.
package org.example;
public class PasswordValidator {
public static void validate(String password) {
}
}
๋ค์๊ณผ ๊ฐ์ด main ํด๋์ค ๋ด ํด๋์ค์ ๋ฉ์๋๋ฅผ ์์ฑํด์ฃผ๊ณ ์๋ฌด ๋ด์ฉ ์์ด ํ ์คํธ๋ฅผ ์งํํด๋ exception์ด ๋ฐ์ํ์ง ์๊ธฐ ๋๋ฌธ์ test pass๋๋ค.
package org.example;
public class PasswordValidator {
private static final String WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE = "๋น๋ฐ๋ฒํธ๋ ์ต์ 8์ ์ด์ 12์ ์ดํ์ฌ์ผ ํฉ๋๋ค.";
public static void validate(String password) {
int length = password.length();
if (length < 8 || length > 12) {
throw new IllegalArgumentException(WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE);
}
}
}
๋ค์๊ณผ ๊ฐ์ด PasswordValidator๋ฅผ ์์ฑํ๊ณ ๋ฆฌํฉํ ๋ง์ ์งํํ๋ค.
์์ธ ํ ์คํธ ์ฝ๋๋ ์์ฑํด์ผ ํ๊ธฐ ๋๋ฌธ์, @ParameterizedTest๋ฅผ ์ด์ฉํ์ฌ ์์ธ ํ ์คํธ๋ฅผ ์งํํ๋ค.
@DisplayName("๋น๋ฐ๋ฒํธ๊ฐ 8์ ๋ฏธ๋ง ๋๋ 12์ ์ด๊ณผ ์์ IllegalArgumentException ์์ธ๊ฐ ๋ฐ์ํ๋ค.")
@ParameterizedTest
@ValueSource(strings = {"aabbcce", "aabbccddeeffg"})
void validatePasswordTest2(String password) {
assertThatCode(() -> PasswordValidator.validate(password))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("๋น๋ฐ๋ฒํธ๋ ์ต์ 8์ ์ด์ 12์ ์ดํ์ฌ์ผ ํฉ๋๋ค.");
}
@ParameterizedTest๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋๋ฐ, ์๋์ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ๋ฉด ์ด๋ค ๋ค์ํ ๋ฐฉ์์ผ๋ก ์๋ํ ์ด์ ์ ํ์ฉํ ์ ์๋์ง ์ ๋์ ์๋ค.
์ผ๋จ์ ์์ ์ฝ๋์ ๊ฐ์ด @ValueSource๋ฅผ ์ด์ฉํด ํ ์คํธ ์ฝ๋์ ํ ์คํธ ํ๊ณ ์ ํ๋ ํ๋ผ๋ฏธํฐ๋ค์ ์ฌ๋ฌ๊ฐ ํ ์คํธ ํด๋ณผ ์ ์๋ค.
https://www.petrikainulainen.net/programming/testing/junit-5-tutorial-writing-parameterized-tests/
JUnit 5 Tutorial: Writing Parameterized Tests
JUnit 5 Tutorial: Writing Parameterized Tests Author: Petri Kainulainen Published: December 19, 2021 This blog post describes how we can write parameterized tests with JUnit 5. After we have finished this blog post, we: Can get the required dependencies wi
www.petrikainulainen.net
'๐ web' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Flutter] ๊พน ๋๋ฅด๊ธฐ ํจ๊ณผ ์ฃผ๊ธฐ (2) | 2024.10.01 |
---|---|
[github] github.io๋ก ๊ฐ๋ฐ์ ํฌํธํด๋ฆฌ์ค ์์ฑํ๊ธฐ ๐๐ป (1) | 2024.09.10 |
๊ณ์ฐ๊ธฐ ์น ํ๋ก๊ทธ๋จ ๊ตฌํ - request line (0) | 2023.09.18 |