Element-UI 基础表单测试(含校验)(SimpleForm.vue)
vue
<template>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="活动名称" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间" required>
<el-col :span="11">
<el-form-item prop="date1">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="ruleForm.date1"
style="width: 100%"
></el-date-picker>
</el-form-item>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-form-item prop="date2">
<el-time-picker
placeholder="选择时间"
v-model="ruleForm.date2"
style="width: 100%"
></el-time-picker>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="即时配送" prop="delivery">
<el-switch v-model="ruleForm.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质" prop="type">
<el-checkbox-group v-model="ruleForm.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源" prop="resource">
<el-radio-group v-model="ruleForm.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式" prop="desc">
<el-input type="textarea" v-model="ruleForm.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')"
>立即创建</el-button
>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
ruleForm: {
name: "",
region: "",
date1: "",
date2: "",
delivery: false,
type: [],
resource: "",
desc: "",
},
rules: {
name: [
{ required: true, message: "请输入活动名称", trigger: "blur" },
{
min: 3,
max: 5,
message: "长度在 3 到 5 个字符",
trigger: "blur",
},
],
region: [
{ required: true, message: "请选择活动区域", trigger: "change" },
],
date1: [
{
type: "date",
required: true,
message: "请选择日期",
trigger: "change",
},
],
date2: [
{
type: "date",
required: true,
message: "请选择时间",
trigger: "change",
},
],
type: [
{
type: "array",
required: true,
message: "请至少选择一个活动性质",
trigger: "change",
},
],
resource: [
{ required: true, message: "请选择活动资源", trigger: "change" },
],
desc: [
{ required: true, message: "请填写活动形式", trigger: "blur" },
],
},
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert("submit!");
} else {
console.log("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
},
};
</script>Element-UI 复杂表单组件测试(含校验)(SimpleForm.spec.js)
js
// src/components/__tests__/SimpleForm.spec.js
import { mount } from "@vue/test-utils";
import SimpleForm from "../JestTest/SimpleForm.vue";
import ElementUI from "element-ui";
import Vue from "vue";
console.warn = jest.fn();
// 全局注册 Element UI(不使用局部 Vue)
Vue.use(ElementUI);
describe("Element-UI 复杂表单组件测试(含校验)", () => {
let wrapper;
beforeEach(() => {
// 每次测试前重新挂载组件
wrapper = mount(SimpleForm);
});
// 测试用例1:表单基础结构渲染验证
test("表单渲染完整的结构和所有字段", () => {
// 验证根表单元素
const form = wrapper.find("form.el-form");
expect(form.exists()).toBe(true);
// 验证所有表单项(共7个输入项 + 1个按钮组)
const formItems = wrapper.findAll(".el-form-item");
console.log("SimpleForm.spec.js", formItems.length);
expect(formItems.length).toBe(10);
// 验证具体字段:活动名称(input)
const nameLabel = formItems.at(0).find(".el-form-item__label");
expect(nameLabel.text()).toBe("活动名称");
expect(formItems.at(0).find(".el-input__inner").exists()).toBe(true);
// 验证具体字段:活动区域(select)
const areaLabel = formItems.at(1).find(".el-form-item__label");
expect(areaLabel.text()).toBe("活动区域");
expect(formItems.at(1).find(".el-select").exists()).toBe(true);
expect(formItems.at(1).find(".el-select__caret").exists()).toBe(true);
// 验证具体字段:活动时间(日期选择器)
const timeLabel = formItems.at(2).find(".el-form-item__label");
expect(timeLabel.text()).toBe("活动时间");
expect(formItems.at(2).find(".el-date-editor").exists()).toBe(true);
expect(formItems.at(2).find(".el-icon-date").exists()).toBe(true);
// 验证具体字段:即时配送(switch)
const deliveryLabel = formItems.at(5).find(".el-form-item__label");
expect(deliveryLabel.text()).toBe("即时配送");
expect(formItems.at(5).find(".el-switch").exists()).toBe(true);
expect(formItems.at(5).find(".el-switch__input").exists()).toBe(true);
// 验证具体字段:活动性质(checkbox-group)
const natureLabel = formItems.at(6).find(".el-form-item__label");
expect(natureLabel.text()).toBe("活动性质");
expect(formItems.at(6).find(".el-checkbox-group").exists()).toBe(true);
expect(formItems.at(6).findAll(".el-checkbox").length).toBe(4); // 4个复选框
// 验证具体字段:特殊资源(radio-group)
const resourceLabel = formItems.at(7).find(".el-form-item__label");
expect(resourceLabel.text()).toBe("特殊资源");
expect(formItems.at(7).find(".el-radio-group").exists()).toBe(true);
expect(formItems.at(7).findAll(".el-radio").length).toBe(2); // 2个单选框
// 验证具体字段:活动形式(textarea)
const formLabel = formItems.at(8).find(".el-form-item__label");
expect(formLabel.text()).toBe("活动形式");
expect(formItems.at(8).find(".el-textarea__inner").exists()).toBe(true);
// 验证按钮组
const buttons = formItems.at(9).findAll(".el-button");
expect(buttons.length).toBe(2);
expect(buttons.at(0).text()).toBe("立即创建"); // 提交按钮
expect(buttons.at(1).text()).toBe("重置"); // 取消按钮
});
// 测试用例2:活动名称必填校验
test("活动名称未输入时,提交触发必填校验", async () => {
// 点击提交按钮
await wrapper.find(".el-button--primary").trigger("click");
await Vue.nextTick(); // 等待校验提示渲染
// 验证第一个表单项(活动名称)出现错误提示
const nameFormItem = wrapper.findAll(".el-form-item").at(0);
const errorMsg = nameFormItem.find(".el-form-item__error");
expect(errorMsg.exists()).toBe(true);
expect(errorMsg.text()).toContain("请输入"); // 匹配"请输入活动名称"
});
// 测试用例2.1:活动名称字数限制
test("活动名称字数限制校验:输入3到5个字符", async () => {
// 1. 填写活动名称(必填)
const nameInput = wrapper.find(
".el-form-item:nth-child(1) .el-input__inner"
);
async function inputText(str, acceptError = false, errMsg = "") {
await nameInput.setValue(str);
await nameInput.trigger("blur");
await Vue.nextTick(); // 等待校验提示渲染
// 验证第一个表单项(活动名称)出现错误提示
const nameFormItem = wrapper.findAll(".el-form-item").at(0);
const errorMsg = nameFormItem.find(".el-form-item__error");
expect(errorMsg.exists()).toBe(acceptError);
if (acceptError) {
expect(errorMsg.text()).toContain(errMsg); // 匹配"请输入活动名称"
}
}
// 2.1.1 少于3个字符
await inputText("活动", true, "长度在 3 到 5 个字符");
// 2.1.2 3-5个字符
await inputText("活动名称", false, "");
// 2.1.3 超过5个字符
await inputText("活动名称123", true, "长度在 3 到 5 个字符");
});
// 测试用例3:活动名称输入后校验通过
test("活动名称输入合法值后,校验错误消失", async () => {
// 找到活动名称输入框并输入内容
const nameInput = wrapper.find(
".el-form-item:nth-child(1) .el-input__inner"
);
await nameInput.setValue("测试活动名称");
await nameInput.trigger("blur"); // 触发失焦校验
setTimeout(() => {
// 验证错误提示消失
const errorMsg = wrapper
.findAll(".el-form-item")
.at(0)
.find(".el-form-item__error");
// console.log("nameInput::", nameInput.element.value);
expect(errorMsg.exists()).toBe(false);
});
});
// 测试用例4:活动区域选择功能
test("活动区域选择后,输入框显示选中值", async () => {
// 点击选择框触发下拉
const selectTrigger = wrapper.find(".el-form-item:nth-child(2) .el-select");
await selectTrigger.trigger("click");
await Vue.nextTick();
// 选择第一个选项(区域一)
const options = wrapper.findAll(".el-select-dropdown__item");
expect(options.length).toBe(2); // 存在2个选项
await options.at(0).trigger("click");
await Vue.nextTick();
// 验证输入框显示选中值
const selectInput = wrapper.find(
".el-form-item:nth-child(2) .el-input__inner"
);
expect(selectInput.element.value).toBe("区域一");
});
// 测试用例5:提交按钮触发表单校验并提交
test("所有必填项填写后,提交触发成功事件", async () => {
// 1. 填写活动名称(必填)
const nameInput = wrapper.find(
".el-form-item:nth-child(1) .el-input__inner"
);
await nameInput.setValue("完整的活动名称");
await nameInput.trigger("blur");
// 2. 选择活动区域
await wrapper
.find(".el-form-item:nth-child(2) .el-select")
.trigger("click");
await Vue.nextTick();
await wrapper.findAll(".el-select-dropdown__item").at(0).trigger("click");
await Vue.nextTick();
// 3. 点击提交按钮
await wrapper.find(".el-button--primary").trigger("click");
await Vue.nextTick();
// 4. 验证无错误提示
setTimeout(() => {
const allErrors = wrapper.findAll(".el-form-item__error");
expect(allErrors.filter((error) => error.exists()).length).toBe(0);
// 5. 验证提交事件触发
expect(wrapper.emitted("submit")).toBeTruthy();
});
});
});