Reactjs 如何防止cypress POST请求在数据库中创建实际数据
我用cypress进行了react应用程序测试。 我正在尝试创建自定义登录命令,以便在整个测试过程中使用它 问题是Reactjs 如何防止cypress POST请求在数据库中创建实际数据,reactjs,cypress,Reactjs,Cypress,我用cypress进行了react应用程序测试。 我正在尝试创建自定义登录命令,以便在整个测试过程中使用它 问题是cy.request('POST','/api/admin/user/register',{userInfo})在数据库中创建了我绝对不想要的实际数据 另一个问题是“登录”按钮没有变为“注销”。在测试中,请求返回200,本地存储中存在令牌。我想需要在cypress中设置“isLoggedIn”状态(登录成功时保存在redux存储中) 我怎样才能工作 commands.js user.
cy.request('POST','/api/admin/user/register',{userInfo})
在数据库中创建了我绝对不想要的实际数据
另一个问题是“登录”按钮没有变为“注销”。在测试中,请求返回200,本地存储中存在令牌。我想需要在cypress中设置“isLoggedIn”状态(登录成功时保存在redux存储中)
我怎样才能工作
commands.js
user.spec.js
navBar.js
const-Navbar=({isLoggedIn,handleUserLogout})=>(
{/*直接从localStoragy调用isLoggedIn()不会在路由器历史更改时重新呈现组件。*/}
{伊斯洛格丁(
注销
) : (
登录
)}
);
我假设您不想写入数据库的原因是因为您的测试使用的数据库/模式与手动开发中使用的数据库/模式相同,并且您不想在每次测试运行时都污染它 但是如果你不写DB,你怎么能测试你的应用呢?我假设在测试生命周期中访问用户数据时,您需要数据库中的实际用户从中检索数据 在任何情况下,真正的问题不是在测试期间将数据写入db,而是db污染 在这种情况下,有两种解决方案:
至于您的第二个问题(您确实应该为其创建一个新问题):您正在将
令牌
存储到Cypress runner窗口
对象上的本地存储
,而不是您的应用程序(AUT)窗口
对象
您需要执行以下操作:
/**/
。然后({body})=>{
cy.window().then(win=>{
win.localStorage.setItem('token',body.token);
});
});
但它无法解决UI不重新提交的问题,因为此登录工作流(我假设)绕过了正常的应用程序登录工作流(通常,您会直接使用UI登录,但这可能不是每个测试的好解决方案).我假设您不想写入数据库的原因是因为您的测试使用的数据库/模式与手动开发中使用的数据库/模式相同,并且您不想每次运行测试时都污染它 但是如果你不写DB,你怎么能测试你的应用呢?我假设在测试生命周期中访问用户数据时,您需要数据库中的实际用户从中检索数据 在任何情况下,真正的问题不是在测试期间将数据写入db,而是db污染 在这种情况下,有两种解决方案:
至于您的第二个问题(您确实应该为其创建一个新问题):您正在将
令牌
存储到Cypress runner窗口
对象上的本地存储
,而不是您的应用程序(AUT)窗口
对象
您需要执行以下操作:
/**/
。然后({body})=>{
cy.window().then(win=>{
win.localStorage.setItem('token',body.token);
});
});
但它无法解决UI不重新提交的问题,因为此登录工作流(我假设)绕过了正常的应用程序登录工作流(通常,您会直接使用UI登录,但这可能不是每个测试的好解决方案)
Cypress.Commands.add('login', userType => {
const types = {
admin: {
username,
companyName,
password,
contactNo,
bankAccountId,
email,
mealPrice,
businessType,
admin: true,
},
user: {
username,
companyName,
password,
contactNo,
bankAccountId,
email,
mealPrice,
businessType,
admin: false,
},
};
const userInfo = types[userType];
return cy
.request('POST', '/api/admin/user/register', { userInfo })
.then(()=>{
cy.route({
url: '/api/auth/login',
method: 'POST',
body: {
username: userInfo.username,
password: userInfo.password,
},
}).then(({ body }) => window.localStorage.setItem('token', body.token));
})
});
describe('user', () => {
beforeEach(() => {});
it('can visit the app', () => {
cy.login('user').then(() => {
expect(window.localStorage.getItem('token')).to.exist;
cy.visit('/');
cy.contains('로그아웃');
});
});
});
const Navbar = ({ isLoggedIn, handleUserLogout }) => (
<div className="flex justify-between">
{/* calling isLoggedIn() directly from localStoragy does not re-render the component on router history change. */}
{isLoggedIn ? (
<button
type="button"
className="nav--login-btn td-none c-text br f-mini"
onClick={handleUserLogout}
>
logout
</button>
) : (
<Link className="nav--login-btn td-none c-text br f-mini" to="/login">
login
</Link>
)}
</div>
);
Cypress.Commands.add('login', userType => {
// visit login page
cy.visit('/login');
const types = {
admin: {
...
},
user: {
...
},
};
// grab the user
const userInfo = types[userType];
// login
cy.get(`[data-testid="username"]`).type(userInfo.username);
cy.get(`[data-testid="password"]`).type(userInfo.password);
cy.get('button[type=submit]').click();
cy.request({
url: '/api/auth/login',
method: 'POST',
body: {
username: userInfo.username,
password: userInfo.password,
},
}).then(({ body }) =>
// save token
cy.window().then(win => {
win.localStorage.setItem('token', body.token);
win.sessionStorage.setItem('keepUserLoggedIn', false);
}),
);
});