API 가 어느정도 준비되었으므로, UI를 만든다. 별도의 프로젝트로 구성해서 API를 호출하는 방식으로 구성한다. 프로젝트명은 fridge-web이라고 정한다. 냉장고 가계부 프로젝트 1을 참고한다. 새 프로젝트에서는 Dependencies를 Web, Thymeleaf, DevTools 세개를 체크한다.
프로젝트가 준비되면, pom.xml 파일을 연다.
위와 같이 맨 마지막에 selenium 의존성을 추가해준다. selenium 은 웹브라우저를 이용한 테스트를 수행할 수 있다. selenium을 사용하려면 WebDriver 를 다운받아야한다. 여기에 접속하면 third party 브라우저 드라이버를 다운받을 수 있다. 냉장고 프로젝트에서는 chrome webdriver 를 다운받아서 적당한곳에 위치해뒀다.
src/main/resources 폴더 아래에 templates/food 폴더를 생성하고 foods.html 파일을 작성한다.
간단한 html 파일을 작성하고 html 태그에 xmlns:th attribute를 선언해둔다. thymeleaf 를 사용하기 위해 미리 namespace를 선언하는 것이다. JSP/JSTL 을 사용해도 좋지만, spring에서 계속 띄워주는 thymeleaf 를 사용한다. thymeleaf와 spring 관련 문서는 여기를 참조한다.
foods html을 View 로 사용하는 Controller도 하나 작성한다.
패키지는 src/main/java/com/poseidon/fridge로 하고, 클래스명은 WebFoodController 로 정한다.
url은 /web/foods 로 정하고 단순하게 view 파일을 호출하도록 메서드를 작성한다.
이제 GET /web/foods url을 호출하면 foods() 메서드가 foods.html 파일을 호출한다. 정상 작동하는지 테스트 클래스를 작성한다.
테스트 클래스명은 WebFoodControllerTests 이다.
클래스 애너테이션에 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) 는 테스트가 실행될때마다 랜덤한 포트번호로 내장서버가 구동한다.
ChromeDriver 객체가 browser 라는 static 멤버변수로 선언되어있고, 랜덤 포트번호를 주입받는 @Value 애너테이션이 int port 멤버변수가 선언되어 있다.
basePath 변수는 localhost이며, static 변수 BASE_URL 은 random port 와 basePath 변수가 결합한 데이터를 담을 변수다.
@BeforeClass 애너테이션은 jUnit 클래스가 테스트를 수행하기 전 실행되고, @AfterClass 는 테스트 수행 후 실행된다.
openBrowser메서드는 selenium thirdparty 드라이버 경로를 System property에 등록하고, browser 변수에 ChromeDriver 객체를 메모리에 할당한다.
browser 인스턴스에 DOM객체를 찾을 수 있도록 10초 정도 타임아웃을 설정한다.
closeBrowser 메서드는 browser 인스턴스에서 실행한 웹브라우져를 종료한다.
setUp메서드는 hostname과 port를 BASE_URL 정적변수에 할당한다.
helloWorld 메서드는 browser 가 불러들일 url 을 get 메서드의 파라미터로 전달하고, DOM에서 h2태그명을 찾아서 그 내용을 가져온다. 해당 내용이 Hello, world! 문자열과 일치하는지를 검증한다.
UI테스트를 위한 테스트 클래스 준비는 끝났다. 다음편부터 본격적으로 UI를 작성하고, fridge 웹서비스를 호출하는 코드를 작성할 것이다.
이전글: 냉장고 가계부 프로젝트 9
다음글: 냉장고 가계부 프로젝트 11
프로젝트가 준비되면, pom.xml 파일을 연다.
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <scope>test</scope> </dependency> </dependencies>
위와 같이 맨 마지막에 selenium 의존성을 추가해준다. selenium 은 웹브라우저를 이용한 테스트를 수행할 수 있다. selenium을 사용하려면 WebDriver 를 다운받아야한다. 여기에 접속하면 third party 브라우저 드라이버를 다운받을 수 있다. 냉장고 프로젝트에서는 chrome webdriver 를 다운받아서 적당한곳에 위치해뒀다.
src/main/resources 폴더 아래에 templates/food 폴더를 생성하고 foods.html 파일을 작성한다.
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Food</title> </head> <body> <h2>Hello, world!</h2> </body> </html>
간단한 html 파일을 작성하고 html 태그에 xmlns:th attribute를 선언해둔다. thymeleaf 를 사용하기 위해 미리 namespace를 선언하는 것이다. JSP/JSTL 을 사용해도 좋지만, spring에서 계속 띄워주는 thymeleaf 를 사용한다. thymeleaf와 spring 관련 문서는 여기를 참조한다.
foods html을 View 로 사용하는 Controller도 하나 작성한다.
패키지는 src/main/java/com/poseidon/fridge로 하고, 클래스명은 WebFoodController 로 정한다.
@Controller @RequestMapping("/web/foods") public class WebFoodController { @GetMapping public String foods() { return "food/foods"; } }
url은 /web/foods 로 정하고 단순하게 view 파일을 호출하도록 메서드를 작성한다.
이제 GET /web/foods url을 호출하면 foods() 메서드가 foods.html 파일을 호출한다. 정상 작동하는지 테스트 클래스를 작성한다.
테스트 클래스명은 WebFoodControllerTests 이다.
@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) public class WebFoodControllerTests { private static ChromeDriver browser; @Value("${local.server.port}") private int port; private String basePath = "http://localhost"; private static String BASE_URL; @BeforeClass public static void openBrowser() { System.setProperty("webdriver.chrome.driver", "/Users/gang-yeongho/Documents/chromedriver"); browser = new ChromeDriver(); browser.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); } @AfterClass public static void closeBrowser() { browser.quit(); } @Before public void setUp() { BASE_URL = basePath + ":" + port; } @Test public void helloWorld() { browser.get(BASE_URL + "/web/foods"); assertThat(browser.findElementByTagName("h2").getText()).isEqualTo("Hello, world!"); } }
클래스 애너테이션에 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) 는 테스트가 실행될때마다 랜덤한 포트번호로 내장서버가 구동한다.
ChromeDriver 객체가 browser 라는 static 멤버변수로 선언되어있고, 랜덤 포트번호를 주입받는 @Value 애너테이션이 int port 멤버변수가 선언되어 있다.
basePath 변수는 localhost이며, static 변수 BASE_URL 은 random port 와 basePath 변수가 결합한 데이터를 담을 변수다.
@BeforeClass 애너테이션은 jUnit 클래스가 테스트를 수행하기 전 실행되고, @AfterClass 는 테스트 수행 후 실행된다.
openBrowser메서드는 selenium thirdparty 드라이버 경로를 System property에 등록하고, browser 변수에 ChromeDriver 객체를 메모리에 할당한다.
browser 인스턴스에 DOM객체를 찾을 수 있도록 10초 정도 타임아웃을 설정한다.
closeBrowser 메서드는 browser 인스턴스에서 실행한 웹브라우져를 종료한다.
setUp메서드는 hostname과 port를 BASE_URL 정적변수에 할당한다.
helloWorld 메서드는 browser 가 불러들일 url 을 get 메서드의 파라미터로 전달하고, DOM에서 h2태그명을 찾아서 그 내용을 가져온다. 해당 내용이 Hello, world! 문자열과 일치하는지를 검증한다.
UI테스트를 위한 테스트 클래스 준비는 끝났다. 다음편부터 본격적으로 UI를 작성하고, fridge 웹서비스를 호출하는 코드를 작성할 것이다.
이전글: 냉장고 가계부 프로젝트 9
다음글: 냉장고 가계부 프로젝트 11