如何解决在 testcafe 中执行相同的测试期间,如何使用与 Json 中写入的值相同的值
我一直在尝试使用通过 fs.write() 函数成功添加的 JSON 中的值,
同一夹具中有两个测试用例,一个用于创建 ID,第二个用于使用该 ID。我可以使用 fs.write() 函数在 json 文件中成功写入 id,并尝试使用导入 json 文件(如 var myid=require('../../resources/id.json') 来使用该 id
json 文件存储了当前执行的正确 id,但我在第二次执行中获得了第一个测试执行的 id。
例如,id:1234 存储在第一次测试执行中,而 id:4567 存储在第二次测试执行中。在第二次测试执行期间,我需要 id:4567 但我得到 1234 这很奇怪,不是吗?
我喜欢用它 t.typeText(ele,myid.orid)
我的 json 文件只包含 id,如 {"orid":"4567"}
我是 Javascript 和 testcafe 的新手,任何帮助将不胜感激
写文件类
const fs = require('fs')
const baseClass =require('../component/base')
class WriteIntoFile{
constructor(orderID){
const OID = {
orderid: orderID
}
const jsonString = JSON.stringify(OID)
fs.writeFile(`resources\id.json`,jsonString,err => {
if (err) {
console.log('Error writing file',err)
} else {
console.log('Successfully wrote file')
}
})
}
}
export default WriteIntoFile
我创建了 2 个不同的类,以便将创建和更新操作分开,并在测试文件中的单个夹具中调用创建和更新顺序的函数
创建订单类
class CreateOrder{
----
----
----
async createNewOrder(){
//get text of created ordder and saved order id in to the json file
-----
-----
-----
const orId= await baseclass.getorderId();
new WriteIntoFile(orId)
console.log(orId)
-----
-----
-----
}
}export default CreateOrder
更新订单类
var id=require('../../resources/id.json')
class UpdateOrder{
async searchOrderToUpdate(){
await t
***//Here,I get old order id that was saved during prevIoUs execution***
.typeText(baseClass.searchBox,id.orderid)
.wait(2500)
.click(baseClass.searchIcon)
.doubleClick(baseClass.orderAGgrid)
console.log(id.ordderid)
----
----
async updateOrder(){
this.searchOrderToUpdate()
.typeText(baseClass.phNo,'1234567890')
.click(baseClass.saveBtn)
}
}export default UpdateOrder
测试文件
const newOrder = new CreateOrder();
const update = new UpdateOrder();
const role = Role(`siteurl`,async t => {
await t
login('id')
await t
.wait(1500)
},{preserveUrl:true})
test('Should be able to create an Order',async t=>{
await newOrder.createNewOrder();
});
test('Should be able to update an order',async t=>{
await update.updateOrder();
});
解决方法
我会回复这个,但你可能不会对我的回答满意,因为我不会像你在代码中提出的那样走这条路。
我可以看到一些问题。其中一些现在可能不是问题,但一个月后,您可能会遇到这个问题。
1/ 您正在创建相互依赖的单独测试用例。
这是一个问题,原因如下:
- 如果
Should be able to create an Order
不运行怎么办?或者如果失败了怎么办?那么Should be able to update an order
也失败了,这个信息是没有用的,因为失败的不是更新操作,而是你没有满足测试用例的所有先决条件 - 您如何确保
Should be able to create an Order
始终在hould be able to update an order
之前运行?不可能!当一个在另一个之前,你可以这样做,我认为它会起作用,但在某些时候,你决定将一个测试移到其他地方,你就会遇到麻烦,你会花几个小时调试它。你为自己准备了一个陷阱。我就这个主题写了 this answer,你可以阅读。 - 你不能并行运行测试
- 当我阅读您的测试文件时,没有明显的迹象表明这些测试是相互依赖的。因此,作为您的代码的陌生人,我很容易把事情搞砸,因为如果不深入代码,我就无法了解它。对于可能会在您之后访问您的代码的任何人来说,这都是一个大陷阱。不要对你的同事这样做。
2/ 当您需要做的只是传递一个值太麻烦时,处理文件太麻烦了。
我真的不明白为什么您需要将 id 相同到一个文件中。稍微好一点的方法(仍然违反 1/)可能是:
const newOrder = new CreateOrder();
const update = new UpdateOrder();
// use a variable to pass the orderId around
// it's also visible that the tests are dependent on each other
let orderId = undefined;
const role = Role(`siteurl`,async t => {
// some steps,I omit this for better readability
},{preserveUrl: true})
test('Should be able to create an Order',async t=>{
orderId = await newOrder.createNewOrder();
});
test('Should be able to update an order',async t=>{
await update.updateOrder(orderId);
});
这样做也稍微弥补了我在 1/ 中所写的,即测试相互依赖的第一眼是不可见的。现在,情况有所改善。
也许更好的方法是使用 t.fixtureCtx
object:
const newOrder = new CreateOrder();
const update = new UpdateOrder();
const role = Role(`siteurl`,{preserveUrl:true})
test('Should be able to create an Order',async t=>{
t.fixtureCtx.orderId = await newOrder.createNewOrder();
});
test('Should be able to update an order',async t=>{
await update.updateOrder(t.fixtureCtx.orderId);
});
同样,我至少可以看到测试是相互依赖的。这已经是一个巨大的胜利。
现在回到你的问题:
在第二次测试执行期间,我需要 id:4567 但我得到 1234 这很奇怪,不是吗?
不,这并不奇怪。您需要该文件:
var id = require('../../resources/id.json')
因此它被加载一次,如果您稍后写入文件,除非您再次读取该文件,否则您将不会读取新内容。 require()
是 Node 中加载模块的一个函数,加载一次是有意义的。
这说明了问题:
const idFile = require('./id.json');
const fs = require('fs');
console.log(idFile); // { id: 5 }
const newId = {
'id': 7
};
fs.writeFileSync('id.json',JSON.stringify(newId));
// it's been loaded once,you won't get any other value here
console.log(idFile); // { id: 5 }
你能做些什么来解决这个问题?
您可以使用fs.readFileSync()
:
const idFile = require('./id.json');
const fs = require('fs');
console.log(idFile); // { id: 5 }
const newId = {
'id': 7
};
fs.writeFileSync('id.json',JSON.stringify(newId));
// you need to read the file again and parse its content
const newContent = JSON.parse(fs.readFileSync('id.json'));
console.log(newContent); // { id: 7 }
这就是我在评论部分警告你的。这太麻烦,效率低下,因为您写入文件然后从文件中读取只是为了获得一个值。
您创建的内容也不是很可读:
const fs = require('fs')
const baseClass =require('../component/base')
class WriteIntoFile{
constructor(orderID){
const OID = {
orderid: orderID
}
const jsonString = JSON.stringify(OID)
fs.writeFile(`resources\id.json`,jsonString,err => {
if (err) {
console.log('Error writing file',err)
} else {
console.log('Successfully wrote file')
}
})
}
}
export default WriteIntoFile
所有这些写入文件的操作都在构造函数中,但构造函数并不是所有这些的最佳位置。理想情况下,您只有变量赋值。当您只执行两个可以轻松放入一行代码的操作时,我也没有看到为什么需要创建一个新类的太多理由:
fs.writeFileSync('orderId.json',JSON.stringify({ orderid: orderId }));
尽量简单。与必须使用类转到单独的文件并解密它在那里做什么相比,它更具可读性。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。