Svelte 및 Jest 테스트를 사용한 I18n

영어, 프랑스어 및 폴란드어로 앱을 빌드해야 하므로 Svelte 앱에 이 세 가지 언어를 설치하고 구성하려고 합니다.

Icreated 내 앱과 나는 또한 설치

나는 svelte-i18n을 사용할 것이다

npm i svelte-i18n


이 패키지를 구성할 시간입니다. 구성 전 파일 main.js는 다음과 같습니다.

import './app.css'
import App from './App.svelte'

const app = new App({
  target: document.getElementById('app')
})

export default app


이제 svelte-i18n 가져오기를 추가합니다.

import './app.css'
import App from './App.svelte'
import { addMessages, init } from 'svelte-i18n'

addMessages('en', {
  hello: 'Hello word!' 
}) // this is my key that I will use after in my App page.

init({
  initialLocale: 'en',
  fallbackLocale: 'en'
}); // here I inicialise and  configure a local language

const app = new App({
  target: document.getElementById('app')
})

export default app


이제 다음과 같이 i18n을 App.svelte로 가져옵니다.

<script>
  import { _ } from 'svelte-i18n'
</script>

<main>
  <h1>{$_('hello')}</h1>
</main>


브라우저에서는 매우 잘 작동하지만 테스트는 실패했습니다. 나중에 처리하겠습니다. 지금은 main.js에 다른 언어를 추가합니다.

import './app.css'
import App from './App.svelte'
import { addMessages, init } from 'svelte-i18n'

addMessages('en', {
  hello: 'Hello word!' 
})

addMessages('fr', {
  hello: 'Salut tout le monde!' 
})

addMessages('pl', {
  hello: 'Witajcie w naszej bajce!' 
})

init({
  initialLocale: 'fr',
  fallbackLocale: 'en'
});

const app = new App({
  target: document.getElementById('app')
})

export default app


따라서 현지 언어를 변경하면 브라우저의 텍스트도 변경됩니다.
내가 언급했듯이 테스트가 손상되었으므로 수정하겠습니다.
먼저 src 폴더에 로케일 폴더를 만듭니다.

mkdir locale
cd locale
touch i18n.js


main.js에서 코드의 이 부분을 잘라냈습니다.

import { addMessages, init } from 'svelte-i18n'

addMessages('en', {
  hello: 'Hello word!' 
})

addMessages('fr', {
  hello: 'Salut tout le monde!' 
})

addMessages('pl', {
  hello: 'Witajcie w naszej bajce!' 
})

init({
  initialLocale: 'fr',
  fallbackLocale: 'en'
});


i18n.js에 붙여넣고 이 파일을 main.js로 가져옵니다.

import './locale/i18n'


번역은 브라우저에서 작동합니다.
이 파일도 App.spec.js 파일로 가져옵니다.

import '../src/locale/i18n'


현지 언어가 영어인 경우 테스트는 녹색입니다.

모든 언어를 동일한 파일에 포함하려면 각 언어에 대한 JSON 파일을 만듭니다.


i18n.js에서 다음 파일을 모두 가져옵니다.

import { addMessages, init } from 'svelte-i18n';
import en from './en.json';
import fr from './fr.json';
import pl from './pl.json';

addMessages('en', en)

addMessages('fr', fr)

addMessages('pl', pl)

init({
  initialLocale: 'en',
  fallbackLocale: 'en'
});


이제 번역이 잘 표시되는지 테스트합니다.

App.spec.js:

/**
 * @jest-environment jsdom
 */

 import App from "../src/App.svelte";
 import { render, screen } from "@testing-library/svelte";
 import '../src/locale/i18n'
 import en from '../src/locale/en.json' //here I import a json files 
 import fr from '../src/locale/fr.json'
 import pl from '../src/locale/pl.json'

 // I modify a little bit a teste by adding description tag 
 describe("App Page", () =>{
   describe("Layout", () =>{
    it("has Hello header", () =>{
      render(App);
      const header = screen.getAllByText("Hello word!");
      expect(header).toBeTruthy()
    });
   });
   describe("i18n", () =>{
     it("displays text in English", () =>{
       render(App);
       expect(screen.queryByRole('heading', {level: 1, name: en.hello})).toBeInDocument; /here I use from json file key and its value
     });
     it("displays text in French", () =>{
      render(App);
      expect(screen.queryByRole('heading', {level: 1, name: fr.hello})).toBeInDocument;
    });
    it("displays text in Polish", () =>{
      render(App);
      expect(screen.queryByRole('heading', {level: 1, name: pl.hello})).toBeInDocument;
    });
   })
 })


잠시 동안 모든 것이 기본이지만 언어를 변경하고 싶기 때문에 언어 간 전환을 위한 작은 버튼을 만들어야 합니다.

테스트에서 다음 두 가지 테스트를 추가합니다.

it("displays text in French after clic a FR btn", async () =>{
      render(App);
      const frBtn = screen.getByText('FR');
      await userEvent.click(frBtn);
      expect(screen.queryByRole('heading', {level: 1, name: fr.hello})).toBeInDocument;
    });
    it("displays text in Polish after clic a PL btn", async () =>{
      render(App);
      const plBtn = screen.getByText('PL');
      await userEvent.click(plBtn);
      expect(screen.queryByRole('heading', {level: 1, name: pl.hello})).toBeInDocument;
    });


그 테스트는 정확하지만 이전에 설치한 라이브러리에서 사용자 이벤트를 가져와야 하기 때문에 작동하지 않습니다.

import userEvent from '@testing-library/user-event'


이제 App.svelte에서 클릭할 요소가 없기 때문에 테스트가 중단되었습니다. 그래서 3개의 언어 요소를 만들고 on:click을 추가합니다. 또한 i18n에서 로컬을 가져와야 합니다. 이제 App.svelte는 다음과 같습니다.

<script>
  import { _, locale } from 'svelte-i18n'
</script>

<main>
  <h1>{$_('hello')}</h1>
  <span on:click = {() => locale.set("en")}>EN</span>
  <span on:click = {() => locale.set("fr")}>FR</span>
  <span on:click = {() => locale.set("pl")} >PL</span>
</main>


이제 모두 작동하지만 EN 버튼이 다른 버튼보다 잘 작동하는지 알아야 하므로 테스트를 하나 더 만듭니다.

it("displays text in English after click from PL btn", async() =>{
      render(App);
      const plBtn = screen.getByText('PL');
      await userEvent.click(plBtn);

      const enBtn = screen.getByText('EN');
      await userEvent.click(enBtn);
      expect(screen.queryByRole('heading', {level: 1, name: en.hello})).toBeInDocument;
    });


따라서 모든 App.spec.js는 다음과 같습니다.

/**
 * @jest-environment jsdom
 */

 import App from "../src/App.svelte";
 import { render, screen } from "@testing-library/svelte";
 import userEvent from '@testing-library/user-event'
 import '../src/locale/i18n'
 import en from '../src/locale/en.json'
 import fr from '../src/locale/fr.json'
 import pl from '../src/locale/pl.json'


 describe("App Page", () =>{
   describe("Layout", () =>{
    it("has Hello header", () =>{
      render(App);
      const header = screen.getAllByText("Hello word!");
      expect(header).toBeTruthy()
    });
   });
   describe("i18n", () =>{
     it("displays text in English by default", () =>{
       render(App);
       expect(screen.queryByRole('heading', {level: 1, name: en.hello})).toBeInDocument;
     });
     it("displays text in French after clic a FR btn", async () =>{
      render(App);
      const frBtn = screen.getByText('FR');
      await userEvent.click(frBtn);
      expect(screen.queryByRole('heading', {level: 1, name: fr.hello})).toBeInDocument;
    });
    it("displays text in Polish after clic a PL btn", async () =>{
      render(App);
      const plBtn = screen.getByText('PL');
      await userEvent.click(plBtn);
      expect(screen.queryByRole('heading', {level: 1, name: pl.hello})).toBeInDocument;
    });
    it("displays text in English after click from PL btn", async() =>{
      render(App);
      const plBtn = screen.getByText('PL');
      await userEvent.click(plBtn);

      const enBtn = screen.getByText('EN');
      await userEvent.click(enBtn);
      expect(screen.queryByRole('heading', {level: 1, name: en.hello})).toBeInDocument;
    });
   })
 })


테스트를 실행하면 모두 녹색입니다.

좋은 웹페이지 즐겨찾기