از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
تست کامپوننت های Vue.js با Vue Test UtilsSoftware تست است process ارزیابی و تأیید اینکه یک محصول یا برنامه نرم افزاری با موفقیت اجرا می شود و وظایف مورد نیاز خود را بدون هیچ خطایی انجام می دهد. آزمایش ممکن است برای برخی از توسعه دهندگان اتلاف وقت به نظر برسد، اما مهم است که برنامه یا اجزای خود را آزمایش کنید اگر می خواهید …
سرفصلهای مطلب
تست نرم افزار است process ارزیابی و تأیید اینکه یک محصول یا برنامه نرم افزاری با موفقیت اجرا می شود و وظایف مورد نیاز خود را بدون هیچ خطایی انجام می دهد. آزمایش ممکن است برای برخی از توسعه دهندگان اتلاف وقت به نظر برسد، اما اگر می خواهید یک برنامه کاربردی خوب بسازید، مهم است که برنامه یا اجزای خود را آزمایش کنید.
Vue Test Utils (VTU) مجموعه ای از توابع کاربردی است که با هدف ساده سازی آزمایش اجزای Vue.js انجام می شود. روش هایی را برای سوار کردن و تعامل با اجزای Vue به صورت ایزوله ارائه می دهد. از زمان انتقال از Vue 2 به Vue 3، نسخه جدیدی از Vue Test Utils به طور خاص برای Vue 3 وجود دارد.
در این مقاله، ما با استفاده از رویکرد تست اول، یک نمونه برنامه میسازیم. ما برخی از موارد استفاده از Vue Test Utils را برای آزمایش مؤلفههای Vue و روش نوشتن یک مؤلفه آسان برای آزمایش با Vue Test Utils پوشش خواهیم داد.
Vue Test Utils چیست؟
با توجه به مستندات، Vue Test Utils (VTU) مجموعه ای از توابع کمکی است که برای ساده سازی آزمایش اجزای Vue.js طراحی شده است. این کتابخانه روشی برای نصب اجزای Vue و تعامل با آنها به صورت ایزوله ارائه می دهد. از این روش ها می توان به عنوان لفاف یاد کرد. در اصل، لفاف انتزاعی از جزء نصب شده است. برخی از توابع کاربردی را ارائه می دهد که آزمایش را آسان تر می کند.
در حالی که کد را وارد تولید می کنید، اجتناب از معرفی اشکال بسیار مهم است. شاید، اگر اشتباهاً یک باگ را به تولید رسانده اید، بخواهید قبل از اینکه به سرورهای تولید برسد، مطلع شوید. آزمایش صحیح پایگاه کد شما را قادر می سازد تا قبل از اینکه آسیبی وارد شود، مشکل را برطرف کنید. بنابراین، اگر در حال ساخت یک پروژه برای طولانی مدت هستید، مهم است که پایگاه کد خود را آزمایش کنید.
راه اندازی محیط تست ما
برای شروع، یک پوشه جدید ایجاد کنید و با اجرای دستور زیر یک پروژه Vue.js را مقداردهی اولیه کنید:
$ npm init vue@latest
دستور بالا نصب و اجرا خواهد شد create-vue، ابزار رسمی داربست پروژه Vue. سپس، چندین ویژگی نصب را نشان می دهد. گزینه های زیر را انتخاب کنید:
✔ Project name: ... <your-project-name>
✔ Add TypeScript? ... No / Yes
✔ Add JSX Support? ... No / Yes
✔ Add Vue Router for Single Page Application development? ... No / Yes
✔ Add Pinia for state management? ... No / Yes
✔ Add Vitest for Unit testing? ... No / Yes
✔ Add Cypress for both Unit and End-to-End testing? ... No / Yes
✔ Add ESLint for code quality? ... No / Yes
✔ Add Prettier for code formatting? ... No / Yes
برای گزینه های «ESLint»، «Prettier» و «JSX support» «بله» و برای بقیه گزینه «نه» را انتخاب کنید. سپس دستور زیر را برای نصب وابستگی ها و راه اندازی سرور توسعه دهنده اجرا کنید:
$ cd <your-project-name>
$ npm install
$ npm run dev
حالا برای اضافه کردن Vue Test Utils، دستور زیر را اجرا کنید:
$ npm install --save-dev @vue/test-utils
# or
$ yarn add --dev @vue/test-utils
Vue Test Utils اساساً چارچوب-آگنوستیک است – شما می توانید آن را با هر تستی که دوست دارید استفاده کنید. ساده ترین راه برای امتحان کردن آن استفاده از آن است شوخی، یک تست دونده محبوب که برای این آموزش از آن استفاده خواهیم کرد.
برای بارگذاری .vue
فایل های با Jest، شما نیاز دارید vue-jest
. برای نصب vue-jest
، دستور زیر را اجرا کنید:
$ npm install --save-dev vue-jest
سپس Jest را نصب کنید:
$ npm install --save-dev jest
یک فایل جدید در پوشه پروژه خود به نام ایجاد کنید jest.config.js
و کد زیر را اضافه کنید:
module.exports = {
preset: "ts-jest",
globals: {},
testEnvironment: "jsdom",
transform: {
"^.+\\.vue$": "vue-jest",
"^.+\\js$": "babel-jest",
},
moduleFileExtensions: ("vue", "js", "json", "jsx", "ts", "tsx", "node"),
};
اگر نمیخواهید خودتان آن را پیکربندی کنید، میتوانید با شبیهسازی مخزن این آموزش همراه باشید. روی GitHub اینجا.
نوشتن اولین آزمون
بیایید روش استفاده از Vue Test Utils را با نوشتن آزمایشی برای یک برنامه آزمایشی ساده مرور کنیم. باز کن App.vue
و یک کامپوننت demo todo ایجاد کنید:
<template>
<div></div>
</template>
<script lang="ts">
export default {
name: "TodoApp",
data() {
return {
todos: (
{
id: 1,
text: "Go to the grocery store",
completed: false,
},
),
};
},
};
</script>
پس از آن، بیایید اولین آزمایش خود را بنویسیم تا تأیید کنیم که یک todo رندر شده است. باز کن App.spec.ts
و تست زیر را اضافه کنید:
import { mount } from "@vue/test-utils";
import App from "./App.vue";
test("renders a todo", () => {
const wrapper = mount(App);
const todo = wrapper.get('(data-test="todo")');
expect(todo.text()).toBe("Go to the grocery store");
});
در تست بالا از mount
از VTU برای رندر کردن کامپوننت. بعد زنگ میزنیم mount
و جزء را به عنوان اولین آرگومان ارسال کنید. در اصل، ما در حال یافتن یک عنصر با انتخابگر هستیم data-test="todo"
– در DOM، به نظر می رسد <div data-test="todo">...</div>
. بعد، ما را صدا می زنیم text
روشی برای دریافت محتوا، که انتظار داریم «برو به فروشگاه مواد غذایی» باشد.
در حال حاضر اگر تست را اجرا کنیم با پیغام خطای زیر ناموفق خواهد بود:
FAIL src/App.spec.ts
✕ renders a todo (13ms)
● renders a todo
Unable to get (data-test="todo") within: <div></div>
آزمایش ناموفق بود زیرا ما هیچ موردی را ارائه نمیدهیم، بنابراین get()
تماس در برگرداندن یک لفاف ناکام است. حالا بیایید به روز کنیم <template>
در App.vue
برای ارائه todos
آرایه:
<template>
<div>
<div v-for="todo in todos" :key="todo.id" data-test="todo">
{{ todo.text }}
</div>
</div>
</template>
با این تغییر بالا، آزمون قبول می شود:
PASS src/App.spec.ts
✓ renders a todo (24ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.092s
Ran all test suites.
✨ Done in 5.51s.
شما اولین تست مؤلفه خود را با موفقیت نوشتید.
به عنوان گام بعدی، این قابلیت را به کاربر اضافه می کنیم تا یک todo جدید ایجاد کند. برای دستیابی به آن، به فرمی با ورودی نیاز داریم تا کاربر بتواند متنی را تایپ کند. بنابراین وقتی کاربر فرم را ارسال می کند، انتظار داریم todo ارائه شود. برای انجام این کار، به تست زیر نگاهی بیندازید:
import { mount } from "@vue/test-utils";
import App from "./App.vue";
test("creates a todo", async () => {
const wrapper = mount(App);
await wrapper.get('(data-test="new-todo")').setValue("New todo");
await wrapper.get('(data-test="form")').trigger("submit");
expect(wrapper.findAll('(data-test="todo")')).toHaveLength(2);
});
در آزمون فوق، ما از آن استفاده می کنیم mount
روش رندر عنصر ما همچنین اظهار داشتیم که تنها 1 کار ارائه شده است – این موضوع روشنتر میشود که ما یک کار اضافی را اضافه میکنیم، همانطور که خط پایانی آزمایش نشان میدهد. برای به روز رسانی input
، ما استفاده می کنیم setValue
روش – این ما را قادر می سازد مقدار ورودی را تنظیم کنیم.
سپس پس از به روز رسانی input
، ما از آن استفاده می کنیم trigger
روشی برای شبیه سازی کاربر ارسال کننده فرم، و سپس ادعا می کنیم که تعداد موارد کار از 1 به 2 افزایش یافته است.
اگر تست را اجرا کنید، شکست می خورد. بنابراین، به روز رسانی App.vue
شامل شود form
و input
عناصر برای قبولی در آزمون:
<template>
<div>
<div v-for="todo in todos" :key="todo.id" data-test="todo">
{{ todo.text }}
</div>
<form data-test="form" @submit.prevent="createTodo">
<input data-test="new-todo" v-model="newTodo" />
</form>
</div>
</template>
<script lang="ts">
export default {
name: "TodoApp",
data() {
return {
newTodo: "",
todos: (
{
id: 1,
text: "Go to the grocery store",
completed: false,
},
),
};
},
methods: {
createTodo() {
this.todos.push({
id: 2,
text: this.newTodo,
completed: false,
});
},
},
};
</script>
در کد بالا، ما از آن استفاده می کنیم v-model
برای اتصال به input
و @submit
برای گوش دادن به فرم ارسالی وقتی فرم ارسال شد، createTodo
فراخوانی می شود و یک todo جدید را در آرایه todos وارد می کند.
PASS src/App.spec.ts
✓ creates a todo (19ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.185s, estimated 2s
Ran all test suites.
✨ Done in 4.71s.
رندر مشروط
VTU (Vue Test Utils) ویژگیهای مختلفی را برای رندر کردن و اثبات وضعیت یک مؤلفه فراهم میکند تا اطمینان حاصل شود که درست رفتار میکند. در مرحله بعد، بیایید روش رندر کامپوننت ها و همچنین روش اطمینان از اینکه محتوای آنها به درستی رندر شده است را بررسی کنیم.
یکی از ویژگی های کلیدی Vue، درج/حذف دینامیک عناصر با استفاده از آن است v-if
. بنابراین، بیایید به روش آزمایش مولفه ای که استفاده می کند نگاه کنیم v-if
:
const Nav = {
template: `
<nav>
<a id="user-profile" href="/profile">User Profile</a>
<a v-if="subscribed" id="subscribed" href="/dashboard">User Dashboard</a>
</nav>
`,
data() {
return {
subscribed: false,
};
},
};
در <Nav>
جزء بالا، پیوندی به نمایه کاربر نشان داده شده است. در همین حال، اگر subscribed
مقدار درست است، ما پیوندی به داشبورد کاربر نشان خواهیم داد. بنابراین، سه سناریو وجود دارد که باید بررسی کنیم که درست عمل می کنند:
- را
/profile
لینک باید نشان داده شود - هنگامی که کاربر مشترک است،
/dashboard
لینک باید نشان داده شود - هنگامی که کاربر مشترک نیست،
/dashboard
لینک نباید نشان داده شود
Vue Test Utils wrapper
دارد get()
روشی که یک عنصر موجود را جستجو می کند. از آن استفاده می کند querySelector
نحو. ما محتوای پیوند داشبورد کاربر را با استفاده از آن اختصاص می دهیم get()
:
test("renders the user dashboard link", () => {
const wrapper = mount(Nav);
const userProfileLink = wrapper.get("#user-profile");
expect(userProfileLink.text()).toEqual("User Profile");
});
شاید اگر get()
متد یک عنصر منطبق با انتخابگر را برنمیگرداند، یک خطا ایجاد میکند و تست شما ناموفق خواهد بود. را get()
روش a را برمی گرداند DOMWrapper
اگر عنصری پیدا شود
با این حال get
روش کار می کند روی این فرض که عناصر وجود دارند و در صورت عدم وجود، خطا ایجاد می کند. استفاده از آن برای اثبات وجود توصیه نمی شود. بنابراین، Vue Test Utils در اختیار ما قرار می دهد find
و exists
مواد و روش ها. آزمون بعدی بیان می کند که اگر subscribed
نادرست است (که به طور پیش فرض چنین است)، پیوند داشبورد کاربر در دسترس نیست:
test("does not render user dashboard link", () => {
const wrapper = mount(Nav);
// Using `wrapper.get` would throw and make the test fail.
expect(wrapper.find("#subscribed").exists()).toBe(false);
});
در تست بالا، متوجه خواهید شد که ما آن را فراخوانی کردیم exists()
روش روی مقدار بازگشتی از .find()
. به این دلیل است find()
، پسندیدن mount()
، همچنین a را برمی گرداند wrapper
. میتوانید فهرستی از روشهای دیگر پشتیبانی شده برای رندر شرطی را بیابید اینجا.
روش تست رویدادهای منتشر شده
در Vue، مؤلفهها از طریق props و با انتشار رویدادها با فراخوانی با یکدیگر تعامل دارند $emit
. حال، بیایید نگاهی به روش تأیید رویدادهایی که به درستی با استفاده از آن منتشر میشوند، بیاندازیم emitted()
عملکرد ارائه شده توسط Vue Test Utils.
بیایید این ساده را بررسی کنیم Counter
جزء زیر دکمه ای دارد که با کلیک کردن روی آن، یک متغیر شمارش داخلی را افزایش می دهد و مقدار آن را منتشر می کند:
const Counter = {
template: '<button @click="handleClick">Increment</button>',
data() {
return {
count: 0,
};
},
methods: {
handleClick() {
this.count += 1;
this.$emit("increment", this.count);
},
},
};
برای تست کامپوننت بالا، باید بررسی کنیم که an increment
رویداد با جدیدترین count
ارزش منتشر می شود.
برای انجام این کار، ما وابسته خواهیم بود روی را emitted()
روش. یک شی را با تمام رویدادهایی که مؤلفه ساطع کرده است و آرگومان های آنها در یک آرایه برمی گرداند. بیایید نگاهی به روش عملکرد آن بیندازیم:
test("emits an event when clicked", () => {
const wrapper = mount(Counter);
wrapper.find("button").trigger("click");
wrapper.find("button").trigger("click");
expect(wrapper.emitted()).toHaveProperty("increment");
});
در تست بالا، اولین چیزی که متوجه خواهید شد این است emitted()
یک شی را برمی گرداند که در آن هر کلید با یک رویداد منتشر شده مطابقت دارد. در این مورد، increment
.
این آزمون الان باید قبول بشه ما مطمئن شدیم که رویدادی را با نام صحیح منتشر کرده ایم. اگر ندیده اید trigger()
روش قبل، نگران نباشید. برای شبیه سازی تعامل کاربر استفاده می شود. شما می توانید در مورد ادعای رویدادهای پیچیده بیاموزید اینجا.
روش تست فرم ها
در این بخش، راههایی را برای تعامل با عناصر فرم، تنظیم مقادیر و راهاندازی رویدادها بررسی میکنیم.
بیایید نگاهی به این فرم اصلی در زیر بیاندازیم:
<template>
<div>
<input type="email" v-model="email" />
<button @click="submit">Submit</button>
</div>
</template>
<script>
export default {
data() {
return {
email: "",
};
},
methods: {
submit() {
this.$emit("submit", this.email);
},
},
};
</script>
یکی از رایجترین راهها برای اتصال و ورودی داده در Vue استفاده از آن است v-model
. بنابراین، برای تغییر مقدار ورودی در VTU، می توانید از setValue
روش. یک پارامتر را می پذیرد، اغلب a string
یا boolean
، و a را برمی گرداند promise
، که پس از به روز رسانی Vue DOM برطرف می شود.
test("sets the value", async () => {
const wrapper = mount(Component);
const input = wrapper.find("input");
await input.setValue("(email protected)");
expect(input.element.value).toBe("(email protected)");
});
در تست بالا می توانید ببینید setValue
را تنظیم می کند value
ویژگی روی عناصر ورودی به آنچه به آن منتقل می کنیم. ما از انتظار استفاده میکنیم تا مطمئن شویم که Vue بهروزرسانی را کامل کرده و این تغییر در DOM منعکس شده است، قبل از اینکه ادعایی داشته باشیم.
هنگام کار با فرم ها و عناصر اکشن، تحریک رویدادها دومین اقدام مهم است. حالا بیایید نگاهی به وضعیت خود بیاندازیم button
از مثال قبلی
<button @click="submit">Submit</button>
به منظور راه اندازی یک رویداد کلیک، می توانیم از آن استفاده کنیم trigger()
روش.
test("trigger", async () => {
const wrapper = mount(Component);
// Trigger the element
await wrapper.find("button").trigger("click");
// Assert some action has been performed, like an emitted event.
expect(wrapper.emitted()).toHaveProperty("submit");
});
در تست بالا، ما را فعال می کنیم click
شنونده رویداد به طوری که جزء اجرا می شود submit
روش. همانطور که ما با setValue
، ما از await استفاده می کنیم تا مطمئن شویم که عملکرد توسط Vue منعکس می شود. سپس می توانیم ادعا کنیم که برخی از اقدامات رخ داده است. در این مورد، ما رویداد درست را منتشر کردیم.
بنابراین بیایید این دو را ترکیب کنیم تا بررسی کنیم که آیا فرم ساده ما ورودی های کاربر را منتشر می کند یا خیر:
test("emits the input to its parent", async () => {
const wrapper = mount(Component);
// Set the value
await wrapper.find("input").setValue("(email protected)");
// Trigger the element
await wrapper.find("button").trigger("click");
// Assert the `submit` event is emitted,
expect(wrapper.emitted("submit")(0)(0)).toBe("(email protected)");
});
برای کسب اطلاعات بیشتر در مورد راه اندازی شنوندگان رویداد پیچیده و آزمایش اجزای ورودی پیچیده با VTU، بیشتر بخوانید اینجا.
Vue Test Utils به شما کمک می کند تا برای اجزای Vue تست بنویسید. با این حال، فقط VTU کارهای زیادی می تواند انجام دهد. شما باید همیشه کدی بنویسید که آزمایش آن آسان تر باشد و تست هایی بنویسید که معنی دار و نگهداری آن ساده باشد. می توانید این راهنما را دنبال کنید روی چگونه کامپوننت هایی بنویسیم که تست آن آسان باشد:
جزئیات پیاده سازی را آزمایش نکنید: همیشه به ورودی ها و خروجی ها از دیدگاه کاربر فکر کنید. ورودی ها – مانند تعامل، پروپوزال ها، جریان های داده، و خروجی هایی مانند – عناصر DOM، رویدادها و عوارض جانبی.
اجزای کوچکتر و ساده تر بسازید: یک قانون کلی وجود دارد که اگر کامپوننت کمتری انجام دهد، تست آن آسانتر خواهد بود. ساختن اجزای کوچکتر باعث میشود که ترکیبپذیرتر و درک آنها آسانتر شود.
قبل از نوشتن کامپوننت، تست بنویسید: اگر از قبل تست بنویسید، نمی توانید کد غیر قابل آزمایش بنویسید. این یکی از مزایای بزرگ نوشتن تست قبل از نوشتن اجزاست.
نتیجه
امیدوارم از خواندن این آموزش لذت برده باشید. ما ابزارهای تست Vue را که به طور خاص برای Vue3 ساخته شده است بررسی کرده ایم. ما برخی از موارد استفاده از Vue Test Utils را برای آزمایش مؤلفههای Vue نشان دادیم و نگاهی به روش راهاندازی یک محیط آزمایشی با VTU، روش انجام رندر شرطی و روش آزمایش رویدادهای منتشر شده و عناصر شکل انداختیم.
منتشر شده در 1403-01-04 13:48:04