You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Behave+Python在BrowserStack运行Appium测试遇授权错误求助

问题:Behave+Python+BrowserStack Appium测试抛出Authorization required错误

项目结构

  • data
    • credentials.yaml
    • parameters.yaml
  • helpers
    • helpers.py

相关文件内容

credentials.yaml

browserstack:
  userName: "superduperusername"
  accessKey: "superduperpaccesskey"

parameters.yaml

browserstack_android:
  platformName: android
  framework: behave
  app: bs://roadtoeldorado
  platforms:
    - platformName: android
      deviceName: Samsung Galaxy S22 Ultra
      platformVersion: 12.0
  browserstackLocal: true
  buildName: bstack-demo
  projectName: BrowserStack Sample
  buildIdentifier: ${BUILD_NUMBER}
  debug: true
  networkLogs: true

helpers.py

import pprint

from appium import webdriver
import yaml


def create_driver(driver_type):
    # Read desired capabilities from parameters.yaml based on driver_type
    with open("data/parameters.yaml", "r") as parameters_file:
        parameters = yaml.safe_load(parameters_file)

    with open("data/credentials.yaml", "r") as credentials_file:
        credentials = yaml.safe_load(credentials_file)

    if driver_type == 'local_android_emulator':
        capabilities = parameters.get('local_android_emulator', {})
        # Create and return the local driver instance
        return webdriver.Remote('http://localhost:4723/wd/hub', capabilities)

    elif driver_type == 'browserstack_android':
        capabilities = parameters.get('browserstack_android', {})
        browserstack_config = credentials.get('browserstack', {})
        capabilities.update({
            **capabilities,
            'browserstack.user': browserstack_config['userName'],
            'browserstack.key': browserstack_config['accessKey'],
        })
        # Create and return the BrowserStack driver instance
        pp = pprint.PrettyPrinter()
        print("\n")
        pp.pprint(capabilities)
        return webdriver.Remote(
            command_executor="https://hub-cloud.browserstack.com/wd/hub",
            desired_capabilities=capabilities
        )

    # Add more cases for other driver types if needed

    else:
        raise ValueError(f"Unsupported driver type: {driver_type}")

environment.py

import os

from helpers.helpers import create_driver


def before_scenario(context, scenario):
    # Check for the environment variable to set the execution mode
    execution_mode = os.environ.get("EXECUTION_MODE", "local_android_emulator")
    context.execution_mode = execution_mode
    # Set up the driver based on execution mode
    if context.execution_mode == "local_android_emulator":
        context.driver = create_driver('local_android_emulator')
    elif context.execution_mode == "browserstack_android":
        context.driver = create_driver('browserstack_android')
    else:
        raise ValueError(f"Unsupported execution mode: {execution_mode}")
    # Add more modes as needed


def after_scenario(context, scenario):
    # Quit the driver after all scenarios have finished
    if hasattr(context, "driver") and context.driver:
        context.driver.quit()

打印的Capabilities

{'app': 'bs://roadtoeldorado',
 'browserstack.key': 'superduperkey',
 'browserstack.user': 'superduperusername',
 'browserstackLocal': True,
 'buildIdentifier': '${BUILD_NUMBER}',
 'buildName': 'bstack-demo',
 'debug': True,
 'framework': 'behave',
 'networkLogs': True,
 'platformName': 'android',
 'platforms': [{'deviceName': 'Samsung Galaxy S22 Ultra',
                'platformName': 'android',
                'platformVersion': 12.0}],
 'projectName': 'BrowserStack Sample'}

运行错误

HOOK-ERROR in before_scenario: WebDriverException: Message: Authorization required

用户尝试过改用JSON格式调用,问题依旧;直接把凭据放入URL认证时,会出现"missing deviceName"错误,怀疑是Capabilities传递有误,寻求问题原因及解决方法。


解决方案

1. 修正凭据不匹配问题

从打印的Capabilities可以看到,browserstack.key的值是superduperkey,但credentials.yaml里的accessKey是superduperpaccesskey,二者完全不匹配,这是授权失败的直接原因。需要将credentials.yaml中的accessKey修改为正确的BrowserStack密钥,或者排查代码中是否存在拼写错误。

2. 调整Capabilities结构

BrowserStack不支持在Capabilities中嵌套platforms数组,必须将设备参数(deviceName、platformVersion)直接放在顶层。修改parameters.yaml:

browserstack_android:
  platformName: android
  framework: behave
  app: bs://roadtoeldorado
  deviceName: Samsung Galaxy S22 Ultra
  platformVersion: 12.0
  browserstackLocal: true
  buildName: bstack-demo
  projectName: BrowserStack Sample
  buildIdentifier: ${BUILD_NUMBER}
  debug: true
  networkLogs: true

3. 简化Capabilities更新逻辑

当前代码中capabilities.update({**capabilities, ...})属于冗余写法,直接添加新键值对即可,避免不必要的解构操作:

capabilities.update({
    'browserstack.user': browserstack_config['userName'],
    'browserstack.key': browserstack_config['accessKey'],
})

4. 处理占位符替换

${BUILD_NUMBER}是环境变量占位符,需要确保运行测试时该变量已被替换为实际值,否则可能导致BrowserStack无法识别构建信息,间接影响授权或设备匹配。

5. 验证BrowserStack Local状态

如果启用了browserstackLocal: true,必须确保BrowserStack Local二进制文件已正确启动并完成连接,未启动的话也会导致连接或授权失败。


内容的提问来源于stack exchange,提问作者vesssori

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 19:59:59