【问题标题】:Functional Testing Node/Express App with Google's reCAPTCHA使用 Google 的 reCAPTCHA 进行功能测试节点/Express 应用程序
【发布时间】:2018-01-16 20:23:22
【问题描述】:

有没有办法在测试期间选择性地禁用中间件?还是我错过了一个可以帮助我解决问题的基本概念?

背景:我正在编写一些功能测试来记录一个使用 Nodejs 和 Express 的部分编写的网站。到目前为止,我正在使用 selenium-webdriver、Mocha 和 Chai 编写测试。我不反对更改应用程序代码或测试工具。我的问题是如何在测试时使用我的 Google reCAPTCHA?目前它已加载到我的注册表中并使用中间件进行验证。如果 process.env.NODE_ENV 设置为测试,我可以禁用 reCAPTCHA,但我觉得完全禁用它不会测试整个站点。这是一些相关的代码。

控制器:

  r.route('/register')
  .get(
    userController.getReturnURL,
    userController.registerForm
  )
  .post(
    userController.validateRegistrationForm,
    userController.validateGoogleCaptcha,
    catchErrors(userController.insertUser),
    catchErrors(userController.sendEmailValidation),
    authController.login
  );

userController.validateGoogleCaptcha 方法

exports.validateGoogleCaptcha = (req, res, next) => {

  const data = {
    secret: process.env.RECAPTCHA_SITE_KEY,
    response: req.body['g-recaptcha-response'],
  };
  axios({
    method: 'post',
    url: `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${req.body['g-recaptcha-response']}`,
    data: data,
    config: { headers: {'Content-Type': 'multipart/form-data' }}
  })
    .then(function (response) {

      req.body.captchaSuccess = response.data.success;
      next();

    })
    .catch(function (response) {

      req.flash('error','Sorry! There was an error on our side in confirming your humanity with Google\'s reCAPTCHA service. Please try again, if you continue to have problems please <a href="/contact">contact us</a>.');

      // register form takes advantage of Google's reCAPTCHA and we need to load the script in the <head> element.
      req.body.jsScripts = ['https://www.google.com/recaptcha/api.js'];
      return res.render('user/registrationForm', {title: 'Register your Personal Account', body: req.body, flashes: req.flash()});

    });
};

到目前为止我的功能注册测试

const ...


describe('Registration Page', () => {

  var server, driver;
  const port = 8888,
    domain = `http://localhost:${port}`;

  before(() => {
    server = app.listen(port);
    driver = new webDriver.Builder()
      .forBrowser('firefox')
      .build();
  });
  after((done) => {
    server.close(done);
    driver.quit();
  });

  it('Should Render the Registration Page', async () => {
    await driver.get(domain);
    await driver.findElement(By.linkText('Register')).click();
    const title = await driver.findElement(By.css('h1')).getText();
      expect(title).to.include('Register');
    const formElements = await driver.findElement(By.css('form#registrationForm'))
      .findElements(By.css('input'));
      expect(formElements).to.have.length(6);
  });


});

这些测试的下一步是开始测试有效和无效的提交。有什么建议、帮助或想法吗?谢谢!

【问题讨论】:

    标签: node.js selenium express recaptcha functional-testing


    【解决方案1】:

    要绕过 google recaptcha 进行测试,您可以使用他们在常见问题页面上提供的特定密钥并将其放在您的 test 环境中:
    https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha-what-should-i-do

    对于 reCAPTCHA v3,为测试环境创建一个单独的密钥。分数可能不 准确,因为 reCAPTCHA v3 依赖于查看真实流量。

    对于 reCAPTCHA v2,请使用以下测试密钥。你永远不会 CAPTCHA 和所有验证请求都将通过。

    站点密钥:6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI

    密钥:6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe

    所以你可以请求这个url来验证recaptcha:

    https://www.google.com/recaptcha/api/siteverify?secret=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe&response=anytoken

    响应是这样的:

    {
      "success": true,
      "challenge_ts": "2019-08-14T07:59:49Z",
      "hostname": "testkey.google.com"
    }
    

    请注意此处的密钥可能会更改,请访问page 获取新的测试密钥。

    【讨论】:

    • 谢谢。不幸的是,我不再处理这个代码库了。希望这对社区有所帮助。
    【解决方案2】:

    我猜你用的是摩卡。

    正如 Google Recaptcha 所做的那样,您无法在没有人工干预的情况下对其进行测试。因此,要测试您的应用程序,您需要绕过或模拟 recaptcha。 为了让你这样做,你应该模拟“userController.validateGoogleCaptcha”,用一个带有(为什么不)延迟和承诺的异步函数来替换它。 使用重新布线 (https://www.npmjs.com/package/rewire)。与要求相同,但可以访问和修改被调用的实例。

    所以我会做这样的事情。

    在您的控制器测试文件中:

    const rewire = require("rewire");    
    const userController = rewire("userController");
    userController.__set__("validateGoogleCaptcha", (req, res, next) => { 
        req.body.captchaSuccess = response.data.success;
        next();
    });
    
    //Then your describe tests ...
    

    现在 userController 被模拟为总是接受所有的 recaptcha。 您现在必须使用 rewire 在您的调用链中替换它。路由器测试可能有点难以模拟,你必须重新设置你的应用程序文件及其测试路由,然后是新的 userController。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-06
      • 1970-01-01
      • 2018-07-06
      • 2017-11-29
      • 2018-11-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      相关资源
      最近更新 更多