python自动化中(包括UI自动化和API自动化)env的作用和使用

Python自动化中环境变量(env)的作用和使用

📋 环境变量在自动化中的核心作用

作用领域 主要用途 好处
​配置管理​ 存储环境相关的配置参数 一套代码多环境运行
​敏感信息保护​ 存储API密钥、密码等敏感数据 不暴露在代码中
​环境切换​ 区分测试、预生产、生产环境 自动化环境切换
​参数化运行​ 动态调整测试参数和行为 灵活控制测试执行

🛠️ 常用工具库对比

工具库 特点 适用场景 安装命令
python-dotenv .env文件加载环境变量 本地开发和测试 pip install python-dotenv
os.environ Python内置,直接使用 简单场景,系统已有变量 内置
​自定义配置类​ 高度定制化 复杂项目结构 自定义实现

📝 环境变量文件(.env)示例

bash 复制代码
# 环境配置
ENVIRONMENT=test
BASE_URL=https://api.example.com
API_VERSION=v1

# API认证
API_KEY=sk_test_1234567890
API_SECRET=sec_9876543210
USERNAME=testuser
PASSWORD=testpass123

# UI自动化配置
BROWSER=chrome
HEADLESS=true
TIMEOUT=30
WAIT_TIME=10

# 数据库配置
DB_HOST=localhost
DB_PORT=5432
DB_NAME=test_db
DB_USER=db_user
DB_PASSWORD=db_pass

# 第三方服务
SLACK_WEBHOOK=https://hooks.slack.com/services/xxx
EMAIL_SMTP=smtp.gmail.com

🚀 UI自动化中的使用示例

1. 基础配置管理

python 复制代码
# config.py
import os
from dotenv import load_dotenv

load_dotenv()  # 加载.env文件

class Config:
    # 浏览器配置
    BROWSER = os.getenv('BROWSER', 'chrome')
    HEADLESS = os.getenv('HEADLESS', 'false').lower() == 'true'
    TIMEOUT = int(os.getenv('TIMEOUT', '30'))
    
    # 应用配置
    BASE_URL = os.getenv('BASE_URL', 'http://localhost:3000')
    ADMIN_USER = os.getenv('ADMIN_USER', 'admin')
    ADMIN_PASSWORD = os.getenv('ADMIN_PASSWORD', 'admin123')
    
    # 测试配置
    SCREENSHOT_ON_FAILURE = os.getenv('SCREENSHOT_ON_FAILURE', 'true').lower() == 'true'

2. Selenium WebDriver配置

python 复制代码
# driver_setup.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from config import Config

def create_driver():
    if Config.BROWSER.lower() == 'chrome':
        options = Options()
        if Config.HEADLESS:
            options.add_argument('--headless')
        options.add_argument('--no-sandbox')
        options.add_argument('--disable-dev-shm-usage')
        
        driver = webdriver.Chrome(options=options)
    
    elif Config.BROWSER.lower() == 'firefox':
        # Firefox配置
        pass
    
    driver.implicitly_wait(Config.TIMEOUT)
    return driver

3. 页面对象模型中使用

python 复制代码
# login_page.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from config import Config

class LoginPage:
    def __init__(self, driver):
        self.driver = driver
        self.wait = WebDriverWait(driver, Config.TIMEOUT)
    
    def login(self, username=None, password=None):
        username = username or Config.ADMIN_USER
        password = password or Config.ADMIN_PASSWORD
        
        self.driver.get(f"{Config.BASE_URL}/login")
        self.driver.find_element(By.ID, "username").send_keys(username)
        self.driver.find_element(By.ID, "password").send_keys(password)
        self.driver.find_element(By.ID, "login-btn").click()
        
        # 等待登录成功
        self.wait.until(EC.url_contains("dashboard"))

🌐 API自动化中的使用示例

1. API客户端配置

python 复制代码
# api_client.py
import requests
import os
from dotenv import load_dotenv
from typing import Dict, Any

load_dotenv()

class APIClient:
    def __init__(self):
        self.base_url = os.getenv('BASE_URL', 'https://api.example.com')
        self.api_key = os.getenv('API_KEY')
        self.api_secret = os.getenv('API_SECRET')
        self.headers = {
            'Authorization': f'Bearer {self.api_key}',
            'Content-Type': 'application/json'
        }
    
    def get(self, endpoint: str, params: Dict = None) -> Any:
        url = f"{self.base_url}/{endpoint}"
        response = requests.get(url, headers=self.headers, params=params)
        response.raise_for_status()
        return response.json()
    
    def post(self, endpoint: str, data: Dict) -> Any:
        url = f"{self.base_url}/{endpoint}"
        response = requests.post(url, headers=self.headers, json=data)
        response.raise_for_status()
        return response.json()

2. 测试用例中使用

python 复制代码
# test_user_api.py
import pytest
from api_client import APIClient
import os

class TestUserAPI:
    @pytest.fixture
    def api_client(self):
        return APIClient()
    
    def test_create_user(self, api_client):
        test_email = os.getenv('TEST_EMAIL', 'test@example.com')
        
        user_data = {
            "name": "Test User",
            "email": test_email,
            "password": "testpass123"
        }
        
        response = api_client.post('users', user_data)
        assert response['email'] == test_email
        assert 'id' in response
    
    def test_get_users(self, api_client):
        users = api_client.get('users')
        assert isinstance(users, list)

3. 多环境测试配置

python 复制代码
# conftest.py
import pytest
import os
from dotenv import load_dotenv

def pytest_configure(config):
    """根据命令行参数加载不同的环境配置"""
    env = config.getoption('--env', default='test')
    env_file = f'.env.{env}'
    
    if os.path.exists(env_file):
        load_dotenv(env_file)
    else:
        load_dotenv()  # 加载默认的.env文件

def pytest_addoption(parser):
    parser.addoption('--env', action='store', default='test', 
                    help='Environment: test, staging, prod')

# 测试用例中可以使用
@pytest.mark.env('staging')
def test_production_ready_features():
    # 只在特定环境运行的测试
    pass

🔧 高级用法和最佳实践(options)

1. 环境验证和默认值

python 复制代码
# env_validator.py
import os
from typing import List

def validate_required_env_vars(required_vars: List[str]):
    """验证必需的环境变量是否已设置"""
    missing_vars = []
    for var in required_vars:
        if not os.getenv(var):
            missing_vars.append(var)
    
    if missing_vars:
        raise EnvironmentError(f"Missing required environment variables: {missing_vars}")

# 在项目启动时验证
REQUIRED_VARS = ['BASE_URL', 'API_KEY', 'DB_HOST']
validate_required_env_vars(REQUIRED_VARS)

2. 类型转换工具函数

python 复制代码
# env_utils.py
import os

def get_env_bool(key: str, default: bool = False) -> bool:
    value = os.getenv(key, '').lower()
    if value in ('true', '1', 'yes', 'on'):
        return True
    elif value in ('false', '0', 'no', 'off'):
        return False
    return default

def get_env_int(key: str, default: int = 0) -> int:
    try:
        return int(os.getenv(key, default))
    except (ValueError, TypeError):
        return default

def get_env_list(key: str, separator: str = ',', default: list = None) -> list:
    default = default or []
    value = os.getenv(key)
    if value:
        return [item.strip() for item in value.split(separator)]
    return default

3. 安全处理敏感信息

python 复制代码
# security_utils.py
import os
from cryptography.fernet import Fernet

class EnvEncryptor:
    def __init__(self, key=None):
        self.key = key or os.getenv('ENCRYPTION_KEY')
        if self.key:
            self.cipher = Fernet(self.key.encode())
    
    def encrypt_value(self, value: str) -> str:
        if self.key:
            return self.cipher.encrypt(value.encode()).decode()
        return value
    
    def decrypt_value(self, encrypted_value: str) -> str:
        if self.key and encrypted_value:
            return self.cipher.decrypt(encrypted_value.encode()).decode()
        return encrypted_value

# 使用示例
encryptor = EnvEncryptor()
secret_password = encryptor.decrypt_value(os.getenv('ENCRYPTED_PASSWORD'))

📊 Git忽略和安全性

.gitignore 配置

避免将env中的数据传到GIT版本库中 而是在CICD工具中进行配置,例如Jenkins中的凭据管理插件Credentials

python 复制代码
# 环境变量文件
.env
.env.*
!.env.example

# 敏感信息
*.key
*.pem
*.cert

# 日志和临时文件
logs/
tmp/

环境模板文件 (.env.example)

bash 复制代码
# 复制此文件为 .env 并填写实际值
BASE_URL=https://api.example.com
API_KEY=your_api_key_here
API_SECRET=your_api_secret_here

BROWSER=chrome
HEADLESS=false
TIMEOUT=30

DB_HOST=localhost
DB_PORT=5432
DB_NAME=your_database
DB_USER=your_username
DB_PASSWORD=your_password

🎯 总结优势

  1. ​安全性​​:敏感信息不进入代码仓库

  2. ​灵活性​​:一套代码适应多环境

  3. ​可维护性​​:配置集中管理,易于修改

  4. ​协作友好​​:团队协作时各自维护本地配置

  5. ​自动化友好​​:CI/CD流水线中容易注入环境变量

通过合理使用环境变量,可以构建出更加健壮、安全和灵活的自动化测试框架。

相关推荐
成成成成成成果3 小时前
Selenium八大元素定位实战指南
功能测试·自动化
我的xiaodoujiao3 小时前
从 0 到 1 搭建完整 Python 语言 Web UI自动化测试学习系列 17--测试框架Pytest基础 1--介绍使用
python·学习·测试工具·pytest
Bellafu6663 小时前
selenium对每种前端控件的操作,python举例
前端·python·selenium
将车2443 小时前
自动化测试脚本环境搭建
python·测试工具·自动化
海祁3 小时前
【python学习】文件操作
python·学习
jianqiang.xue3 小时前
单片机图形化编程:课程目录介绍 总纲
c++·人工智能·python·单片机·物联网·青少年编程·arduino
Siren_dream4 小时前
python进阶_Day8
开发语言·python
姬嘉晗-19期-河北工职大4 小时前
HCL设备启动失败
python·终端·anaconda·解释器
淬炼之火4 小时前
基于pycharm和anaconda的yolo简单部署测试
python·深度学习·yolo·pycharm·ultralytics