6.1 Given-When-Then์ผ๋ก ํ ์คํธ ๊ตฌ์กฐํ
JUnit์ ์๋ฐ ํด๋์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์ํ์ง ์์ง๋ง ์๋ฐ์์ ๋จ์ ํ ์คํธ ์์ฑํ๋ ์ฌ์ค์์ ํ์ค์ด๋ค.
๋ฉ์๋์ @Test๋ง ์ถ๊ฐํ๋ฉด JUnit์ด ์์์ ํ ์คํธ๋ก ์คํํ๋ค.
๋ฌธ์ ์ฝ๋
@Test
void setPlanetarySpeedIs7667() {
CruiseControl cruiseControl = new CruiseControl();
cruiseControl.setPreset(SpeedPreset.PLANETARY_SPEED);
Assertions.assertTrue(7667 == cruiseControl.getTargetSpeedKmh());
}
์ ํ ์คํธ๋ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๋ ์ข ๋ ์ฝ๋๋ฅผ ๊ตฌ์กฐํํ์ฌ ์ฝ๊ธฐ ์ฝ๊ฒ ๋ฐ๊ฟ ์๋ ์๋ค.
given, when, then ๊ตฌ์กฐ๋ฅผ ์ด์ํ์ฌ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์.
void otherTest() {
// given
CruiseControl cruiseControl = new CruiseControl();
// when
cruiseControl.setPreset(SpeedPreset.PLANETARY_SPEED);
// then
Assertions.assertTrue(7667 == cruiseControl.getTargetSpeedKmh());
}
- given : ํ ์คํธํ๋ ค๋ ๊ธฐ๋ฅ์ ์คํํ๊ธฐ ์ํ ์ ์ ์กฐ๊ฑด
- when : ์ค์ ๋ก ํ ์คํธํ๋ ค๋ ์ฐ์ฐ์ ์ํ
- then : when์์ ์ํํ ๊ฒฐ๊ณผ๊ฐ ์ค์ ๋ก ๊ธฐ๋ํ๋ ๊ฒฐ๊ณผ์ธ์ง ๊ฒ์ฆ (assertion)
์ด๋ ๊ฒ ์ธ ๊ฐ์ง๋ก ํ ์คํธ๋ฅผ ๊ตฌ์กฐํํ๋ฉด ๊ฐ ๋ถ๋ถ์ด ๋ ๋ช ํํ ๋๋ฌ๋๋ค.
6.2 ์๋ฏธ ์๋ ์ด์์ ์ฌ์ฉํ๊ธฐ
'assertTrue()' ๋ง๊ณ 'assertEquals()' ๋ฅผ ์ฌ์ฉํ์.
Assertions.assertTrue(7667 == cruiseControl.getTargetSpeedKmh());
assertTrue ์ฌ์ฉ ์ ์ฑ๊ณต ์์๋ ๋ฌธ์ ์์ด ์๋ํ์ง๋ง
์คํจ ์ 'java.lang.AssertionError'๋ผ๋ ์คํ์ถ์ ์ ๋ฐ๋๋ฐ ์ฌ๊ธฐ์ ์ฃผ์ด์ง ์ ๋ณด๋ (์คํจํ ํด๋์ค, ์คํจํ ์ค ๋ฒํธ)๋ง๊ณ ์ด๋ ํ ๋ฉ์์ง๋ ์๋ค. ๋ฐ๋ผ์, ์ด๋ค ์ด์์ ์ด ์ ์คํจํ๋์ง ์ ์ ์๋ค..
๊ทธ๋ ๋ค๋ฉด ๋ ์์ธํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ป๊ธฐ ์ํด ์ด์์ ์ ์ ๋ณด๋ฅผ ๋ฃ์ผ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น??
Assertions.assertEquals(7667, cruiseControl.getTargetSpeedKmh());
assertEquals๋ฅผ ์ฌ์ฉํ๋ฉด JUnit ํ ์คํธ ์คํจ ์ ํจ์ฌ ๋์ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ค. --> ex) expected <7667> but was <1337>
์ด์ธ์๋ ๋ง์ assertion์ด ์๋ค. ๊ฐ ํ ์คํธ์ ์ํฉ์ ๋ง์ถฐ ๊ฐ์ฅ ์ ํฉํ ์ด์์ ์ ์ ํํ๋ ๊ฒ์ด ์ค์ํ๋ค.
6.3 ์ค์ ๊ฐ๋ณด๋ค ๊ธฐ๋ ๊ฐ์ ๋จผ์ ๋ณด์ด๊ธฐ
('๊ธฐ๋', '์ค์ ')
assertionEquals() ์ฌ์ฉ์ ์ฃผ์ํ ์ !!
assertEquals(์ฒซ๋ฒ์งธ ์ธ์ = ๊ธฐ๋๊ฐ, ๋๋ฒ์งธ ์ธ์ = ์ค์ ๊ฐ)
์ฒซ๋ฒ์งธ ์ธ์๋ ๊ธฐ๋๊ฐ, ๋๋ฒ์งธ ์ธ์๋ ์ค์ ๊ฐ์ผ๋ก ๋ค์ด๊ฐ๋ ์ธ์ ์์๋ฅผ ๊ผญ ์ง์ผ์ผ๋ง ํ๋ค.
์ด๋ฌํ ์ธ์์ ์์๋ฅผ ์๋ชป ์ ๋ ฅํ๊ฒ ๋๋ฉด ๋ฉ์์ง๋ฅผ ์ค์ธํ๊ฒ ๋๊ณ ์ด๋ ์๋ชป๋ ๋๋ฒ๊น ์ผ๋ก ๋์ฑ ๊น์ ์ค๋ฅ๋ก ๋น ์ง๊ฒ ๋ ์ ์๋ค.
์ด๋ ๋งค์ฐ ์ฌ์ํ์ง๋ง ์ค์ํ ๋ฌธ์ ์ด๋ค.
6.4 ํฉ๋นํ ํ์ฉ๊ฐ ์ฌ์ฉํ๊ธฐ
@Test
void testFilling() {
OxygenTank tank = OxygenTank.withCapacity(100);
tank.fill(5.8);
tank.fill(5.6);
Assertions.assertEquals(0.114, tank.getStatus());
}
์ ์ฝ๋๋ 0.114์ ํฑํฌ์ ์ํ๊ฐ์ ๋น๊ตํ๋ค. ํ์ง๋ง ์ด ํ ์คํธ๋ ์์์น ๋ชปํ๊ฒ ์คํจํ ํ๋ฅ ์ด ์๋ ์ฝ๋์ด๋ค.
์๋๋ฉด ๋ถ๋์์์ ์ฐ์ฐ์ ํํํ ์ ์๋ ๋นํธ ์๋ ์ ํ์ ์ด๊ธฐ ๋๋ฌธ์ ์์ฃผ์์ฃผ ์์ ์ค์ฐจ๋ ์ฉ์ธํ๊ณ ๊ทผ์ฌ๊ฐ์ผ๋ก ๋ฐ๋๊ฒ ๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ํ๋ ๊ฐ๊ณผ ์ค์ ๊ฐ์ ๊ทผ์ฌ ๊ฐ์ด ๋ค๋ฅผ ์ ์๋ค.
๋ฐ๋ผ์, ๋ถ๋์์์ ์ฐ์ฐ์ ํ ์คํธํ ๋๋ ๋ฐ๋์ ์์ซ์ ์๋ฆฟ์๋ฅผ ๋ช ์ํด์ผ๋ง ํ๋ค.
๊ฐ์ ์ฝ๋ (3๋ฒ์งธ ์ธ์๋ก ๋ช๋ฒ์งธ ์๋ฆฌ๊น์ง ์ฐจ์ด๋ฅผ ๊ฐ์ ๊ฐ์ผ๋ก ๋ณผ ๊ฒ์ธ์ง ์ธ์๋ฅผ ๋๊น)
static final double TOLERANCE = 0.00001;
@Test
void testFilling() {
OxygenTank tank = OxygenTank.withCapacity(100);
tank.fill(5.8);
tank.fill(5.6);
Assertions.assertEquals(0.114, tank.getStatus(), TOLERANCE);
}
6.5 ์์ธ ์ฒ๋ฆฌ๋ JUnit์ ๋งก๊ธฐ๊ธฐ
๋ฌธ์ ์ฝ๋
class LogbookTest {
@Test
void readLogbook() {
Logbook logbook = new Logbook();
try {
List<String> entries = logbook.readAllEntries();
Assertions.assertEquals(13, entries.size());
} catch (IOException e) {
Assertions.fail(e.getMessage());
}
}
@Test
void readLogbookFail() {
Logbook logbook = new Logbook();
try {
logbook.readAllEntries();
Assertions.fail("read should fail");
} catch (IOException ignored) {}
}
}
๋ ํ ์คํธ ๋ชจ๋ ์ ์ ์คํ๋์ง๋ง ๋จ์ ์ ๊ฐ์ง๋ค.
์ฒซ๋ฒ์งธ ํ ์คํธ๋ '์์ธ์ฌ์ฌ'์ด ๊นจ์ง๋ค. ๋ฉ์์ง๋ง ์ ๊ณตํ ๋ฟ ์ ์ฒด ์์ธ๋ฅผ ์คํ ์ถ์ ์ผ๋ก ์ ๊ณตํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋๋ฒ์งธ ํ ์คํธ๋ ์์ธ๊ฐ ์ผ์ด๋๊ธธ ๊ธฐ๋ํ์ง๋ง ์ฝ๋๋ก๋ ์ ์์ธ๊ฐ ์ผ์ด๋์ผ๋ง ํ๋์ง ์ ์ ์๋ค...
๊ฐ์ ์ฝ๋
class LogbookTest {
@Test
void readLogbook() throws IOException {
Logbook logbook = new Logbook();
List<String> entries = logbook.readAllEntries();
Assertions.assertEquals(13, entries.size());
}
@Test
void readLogbookFail() {
Logbook logbook = new Logbook();
Executable when = () -> logbook.readAllEntries();
Assertions.assertThrows(IOException.class, when);
}
}
ํ ์คํธ์์ ์์ธ๋ฅผ ๋ช ์์ ์ผ๋ก ์ถ๊ฐํ์ง ๋ง๊ณ ๊ทธ๋ฅ JUnit์ด ์์์ ํ๊ฒ ๋๋๋ฉด ๋๋ค.
์ฒซ๋ฒ์งธ ํ ์คํธ์์ try์ fail์ ๋นผ๋ '์์ธ ์ฌ์ฌ'์ด ๊นจ์ง์ง ์์ผ๋ฉด์ ์ ์ฒด ์คํ ์ถ์ ๋ ์ ๊ณตํ๋ค.
๋๋ฒ์งธ ํ ์คํธ์์๋ try-catch ๋์ assertThrows๋ฅผ ์ด์ฉํ์ฌ ์ธ์๋ก ์์ธ๊ฐ ์๊ธฐ๊ธธ ๋ฐ๋ผ๋ ๋ฉ์๋๋ฅผ ์ ๋ฌํ๊ณ ์ด๋ค ์ข ๋ฅ์ ์์ธ๋ฅผ ๋ฐ๋ผ
๋์ง๋ ๋ช ์ํ๋ค.
6.6 ํ ์คํธ ์ค๋ช ํ๊ธฐ
์ข์ ์ฝ๋
class OxygenTankTest {
static final double PERMILLE = 0.001;
@Test
@DisplayName("Expect 44% after filling 22l in an empty 50l tank")
@Disabled("We don't have small tanks anymore! TODO: Adapt for big tanks")
void fillTank() {
OxygenTank smallTank = OxygenTank.withCapacity(50);
smallTank.fill(22);
Assertions.assertEquals(0.44, smallTank.getStatus(), PERMILLE);
}
@Test
@DisplayName("Fail if fill level > tank capacity")
void failOverfillTank() {
OxygenTank bigTank = OxygenTank.withCapacity(10_000);
bigTank.fill(5344.0);
Executable when = () -> bigTank.fill(6000);
Assertions.assertThrows(IllegalArgumentException.class, when);
}
}
์ ์ฝ๋๋ Given-When-Then ๊ตฌ์กฐ, ํฉ๋นํ ํ์ฉ๊ฐ, JUnit์ ์์ธ์ฒ๋ฆฌ๋ฅผ ๋งก๊ธฐ๋ ํ๋์ ํ๋ฉฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๊ณ ์๋ค.
๊ฑฐ๊ธฐ์ ํ ์คํธ์ ๋ํ '์ด๋ฆ'๊ณผ '์ค๋ช ์'๊ฐ ์ถ๊ฐ๋์ด ํ์ธต ๋ ์ข์ ํ ์คํธ ์ฝ๋์ด๋ค.
ํ ์คํธ์ ์คํจํ์ ๋ ์ข์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๊ธฐ ์ํด์ ์ข์ ๋ฉ์๋๋ช ๊ณผ ํ ์คํธ ์ค๋ช ์ด ํ์ํ๋ค.
testfill2() ๋์ failOverfillTank() ์ฒ๋ผ ์๋๋ฅผ ๋ค์ด๋ด๋ ๋ฉ์๋ ๋ช ์ ์ฌ์ฉํด์ผ ํ๋ค. (์ค๋ฅ์ ํ ์คํธ๋ช ์๋ฏธ์๋ ํ ์คํธ ๋ช ๋ ธ์ถ)
@DisplayName("ํ ์คํธ ์ค๋ช ") ์ ์ฌ์ฉํ๋ฉด ๋ฉ์๋๋ช ์ ๋ฐ๊พธ์ง ์๊ณ ๋ ํ๋ฅญํ ํ ์คํธ ์ค๋ช ์ ์ถ๊ฐํ ์ ์๋ค.
๋ํ, @DisplayName์ ์ด์ฉํด ๋นํ์ฑํํ ํ ์คํธ์ ๋ํด ์ ๋นํ์ฑํํ๋์ง ์ด์ ๋ ์ ์ ์ ์๋ค.
6.7 ๋ ๋ฆฝํ ํ ์คํธ ์ฌ์ฉํ๊ธฐ
๋ฌธ์ ์
@BeforeEach ์ @BeforeAll ํ๊ธฐ๋ฅผ ์ธ ๋ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์ ์ด ์๋ค.
๋ ํ๊ธฐ๋ ํ ์คํธ์ given์ ํด๋นํ๋ ํ์ํ ๊ณตํต ์ค์ ์ฝ๋๋ฅผ ์ถ์ถํด ํ๋ฒ๋ง ์์ฑํ ์ ์๊ฒ ํด์ค๋ค.
ํ์ง๋ง ์ด๋ ํ ์คํธ ์ ์ฒด๋ฅผ ์ดํดํ๊ธฐ ์ด๋ ค์์ง๋ ํ์์ด ๋ฐ์ํ๋ค.
ํด๋์ค ์ ์ฒด๋ฅผ ์ฝ์ง ์๊ฑฐ๋ ํ ์คํธ๊ฐ ๋งค์ฐ ๋ง์ ์ํฉ์ ๊ฐ์ ํด๋ณด์.
์ด๋ ๋ง์ฝ ํ ์คํธ๊ฐ ์คํจํ๊ฒ๋๋ฉด ์คํจํ ํ ์คํธ ๋ฉ์๋๋ก ๊ฐํ ๋ given ๋ถ๋ถ์ด ์ด๋์ธ์ง ์ฝ๊ฒ ์ฐพ์ ์ ์๋ค. (์ฌ๋ฌ ์ค์ ๋ฉ์๋๊ฐ ํด๋์ค ๊ณ์ธต ๊ตฌ์กฐ์ ํผ์ ธ์๋ ๋ณต์กํ ์ฝ๋ ์ผ ๋..)
๊ฐ์ ์ฝ๋
class OxygenTankTest {
static OxygenTank createHalfFilledTank() {
OxygenTank tank = OxygenTank.withCapacity(10_000);
tank.fill(5_000);
return tank;
}
@Test
void depressurizingEmptiesTank() {
OxygenTank tank = createHalfFilledTank();
tank.depressurize();
Assertions.assertTrue(tank.isEmpty());
}
@Test
void completelyFillTankMustBeFull() {
OxygenTank tank = createHalfFilledTank();
tank.fillUp();
Assertions.assertTrue(tank.isFull());
}
}
given, when, then ๋ถ๋ถ์ ํ๋์ ํ ์คํธ ์์์ ๋ฐ๋ก ์ฐ๊ฒฐํ๋ฉด '๋ ๋ฆฝ์ ์ธ ํ ์คํธ'๊ฐ ๋๋ค.
createHalfFilledTank()์ฒ๋ผ static ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ณต ์ฝ๋๊ฐ ์๋๋ฉด์ ๊ฐ ํ ์คํธ๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ์ดํดํ ์ ์๊ฒ ๋๋ค.
๋ชจ๋ ์ข ์์ฑ์ ๋ช ์์ ์ผ๋ก ํ์ํ์ผ๋ฏ๋ก ํ๋ก๊ทธ๋๋จธ๋ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ฌ์์ง๊ณ ์ค๋ฅ๋ ์ข ๋ ์ฝ๊ฒ ์ฐพ์ ์ ์๋ค.
@BeforeEach ์ @BeforeAll ํ๊ธฐ๋ ์๋ฌต์ ์ข ์์ฑ์ ๋ง๋ค์ด๋ด๋ฏ๋ก ๊ฐ๋ฅํ๋ฉด ์ฌ์ฉํ์ง ๋ง์. (๋์ static ๊ณต์ฉ ๋ฉ์๋ ์ฌ์ฉ)
6.8 ํ ์คํธ ๋งค๊ฐ ๋ณ์ํ
์ฌ๋ฌ ๋ค์ํ ์ ๋ ฅ ๋งค๊ฐ๋ณ์๋ก ํ ์คํธํด์ผ ํ ๋๊ฐ ์๋ค.
class DistanceConversionTest {
@Test
void testConversionRoundTrip() {
assertRoundTrip(1);
assertRoundTrip(1_000);
assertRoundTrip(9_999_999);
}
private void assertRoundTrip(int kilometers) {
Distance expectedDistance = new Distance(
DistanceUnit.KILOMETERS,
kilometers
);
Distance actualDistance = expectedDistance
.convertTo(DistanceUnit.MILES)
.convertTo(DistanceUnit.KILOMETERS);
Assertions.assertEquals(expectedDistance, actualDistance);
}
}
๋ชจ๋ ๊ฒ์ฆ์ด ํ์ํ ๊ฒฝ์ฐ์ ์์ ๋ํด ํ๋ผ๋ฏธํฐ ๊ฐ์ ๋ฐ๋ก ๋ฃ์ด์ค์ผ ํ๋ค.
๋ง์ฝ, ํ๋ผ๋ฏธํฐ '1'์์ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ํ๋ผ๋ฏธํฐ '1000'์ ๊ฒ์ฆ๋ ๋ชปํด๋ณด๊ฒ ๋๋ค..
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํ๋ค.
๊ฐ์ ์ฝ๋
class DistanceConversionTest {
@ParameterizedTest(name = "#{index}: {0}km == {0}km->mi->km")
@ValueSource(ints = {1, 1_000, 9_999_999})
void testConversionRoundTrip(int kilometers) {
Distance expectedDistance = new Distance(
DistanceUnit.KILOMETERS,
kilometers
);
Distance actualDistance = expectedDistance
.convertTo(DistanceUnit.MILES)
.convertTo(DistanceUnit.KILOMETERS);
Assertions.assertEquals(expectedDistance, actualDistance);
}
}
@ParameterizedTest(name = "#{index}: {0}km == {0}km->mi->km")
@ValueSource(ints = {1, 1_000, 9_999_999})
ํ๊ธฐ๋ก ํ ์คํธ๋ฅผ ๋งค๊ฐ๋ณ์ํ ํ ์ ์๋ค. ์ฆ, '๋งค๊ฐ๋ณ์' ์ 'ํ ์คํธ์ฝ๋'๋ฅผ ๋ถ๋ฆฌํ๋ ๊ฒ์ด๋ค.
์คํํด๋ณด๋ฉด JUnit์ ๊ฐ ๋งค๊ฐ๋ณ์๋ง๋ค ๋ณ๊ฐ์ ํ ์คํธ๋ฅผ ์คํ์ํจ๋ค.
6.9 ๊ฒฝ๊ณ ์ผ์ด์ค ๋ค๋ฃจ๊ธฐ
์ฐ๋ฆฌ๋ ๋งค๊ฐ๋ณ์์ ๋ค์ด์ฌ ์ ์๋ ๋ชจ๋ ๊ฐ๋ค์ ํ ์คํธ ํ ์ ์๋ค.
๋ฐ๋ผ์ ํ๋ฆฌ๊ธฐ ์ฌ์ด '๊ฒฝ๊ณ ์ผ์ด์ค'๋ฅผ ๋ค๋ค์ผ๋ง ํ๋ค.
(๊ฒฝ๊ณ์ผ์ด์ค ์์)
๋ฌธ์์ด -> null, "", " ", "aโ¬…ห∑s",
int -> 0, 1, -1, MAX, MIN
Object[] -> null, {}, {null} ..
๊ฒฝ๊ณ ์ผ์ด์ค ํ ์คํธ ์ฝ๋ ์์
class TransmissionParserTest {
// ์ฌ๋ฐ๋ฅด๊ฒ parseํ๋ ์ง ์ฒดํฌ
@Test
void testValidTransmission() {
TransmissionParser parser = new TransmissionParser();
Transmission transmission = parser.parse("032Houston, UFO sighted!");
Assertions.assertEquals(32, transmission.getId());
Assertions.assertEquals("Houston, UFO sighted!",
transmission.getContent());
}
// null ์
๋ ฅ ์ IllegalArgumentException์ด ์ ๋ฐ์ํ๋์ง ์ฒดํฌ
@Test
void nullShouldThrowIllegalArgumentException() {
Executable when = () -> new TransmissionParser().parse(null);
Assertions.assertThrows(IllegalArgumentException.class, when);
}
// ์ด์ํ ํน์๋ฌธ์ ์
๋ ฅ ์ ์์ธ๊ฐ ์ ๋ฐ์ํ๋์ง ์ฒดํฌ
@Test
void malformedTransmissionShouldThrowIllegalArgumentException() {
Executable when = () -> new TransmissionParser().parse("tอกษฌษชลษn");
Assertions.assertThrows(IllegalArgumentException.class, when);
}
}
6.10 6์ฅ์์ ๋ฐฐ์ด ๋ด์ฉ
ํ ์คํธ ์ฝ๋๋ ์ค์ ๊ธฐ๋ฅ ๊ตฌํ ๋ณด๋ค ๋ ๋ง์ด ์์ฑํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
๋ฐ๋ผ์, ํ ์คํธ ์งํฉ์ ์ ๋์์ธํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํ๋ค.
ํ ์คํธ๋...
given-then-when +
๋ ๋ฆฝ์ ์ด๋ฉฐ ํ๊ธฐ๋ฅผ ํตํด ์ค๋ช ํด์ผํ๋ฉฐ +
์ ์ ํ ์ด์์ ์ ์ ํํจ์ผ๋ก ํ ์คํธ ์ดํด๋๋ฅผ ๋์ฌ์ผ ํ๋ค.
'๐์ฝ์ ์ฑ ์ ๋ฆฌ > ์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 8์ฅ : ๋ฐ์ดํฐ ํ๋ฆ (0) | 2021.04.16 |
---|---|
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 7์ฅ : ๊ฐ์ฒด ๋์์ธ (0) | 2021.04.15 |
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 5์ฅ : ๋ฌธ์ ๋ฐ์์ ๋๋นํ๊ธฐ (0) | 2021.04.14 |
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 4์ฅ : ์ฌ๋ฐ๋ฅด๊ฒ ๋ช ๋ช ํ๊ธฐ (0) | 2021.04.13 |
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 3์ฅ : ์ฌ๊ธฐ๋กญ๊ฒ ์ฃผ์ ์ฌ์ฉํ๊ธฐ (0) | 2021.04.09 |