python自动化中(包括UI自动化和API自动化)env的作用和使用
Python自动化中环境变量(env)的作用和使用
📋 环境变量在自动化中的核心作用
作用领域 | 主要用途 | 好处 |
---|---|---|
配置管理 | 存储环境相关的配置参数 | 一套代码多环境运行 |
敏感信息保护 | 存储API密钥、密码等敏感数据 | 不暴露在代码中 |
环境切换 | 区分测试、预生产、生产环境 | 自动化环境切换 |
参数化运行 | 动态调整测试参数和行为 | 灵活控制测试执行 |
🛠️ 常用工具库对比
工具库 | 特点 | 适用场景 | 安装命令 |
---|---|---|---|
| 从 | 本地开发和测试 |
|
| Python内置,直接使用 | 简单场景,系统已有变量 | 内置 |
自定义配置类 | 高度定制化 | 复杂项目结构 | 自定义实现 |
📝 环境变量文件(.env)示例
# 环境配置
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. 基础配置管理
# config.py
import os
from dotenv import load_dotenvload_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配置
# driver_setup.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from config import Configdef 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配置passdriver.implicitly_wait(Config.TIMEOUT)return driver
3. 页面对象模型中使用
# 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 Configclass LoginPage:def __init__(self, driver):self.driver = driverself.wait = WebDriverWait(driver, Config.TIMEOUT)def login(self, username=None, password=None):username = username or Config.ADMIN_USERpassword = password or Config.ADMIN_PASSWORDself.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客户端配置
# api_client.py
import requests
import os
from dotenv import load_dotenv
from typing import Dict, Anyload_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. 测试用例中使用
# test_user_api.py
import pytest
from api_client import APIClient
import osclass TestUserAPI:@pytest.fixturedef 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_emailassert 'id' in responsedef test_get_users(self, api_client):users = api_client.get('users')assert isinstance(users, list)
3. 多环境测试配置
# conftest.py
import pytest
import os
from dotenv import load_dotenvdef 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. 环境验证和默认值
# env_validator.py
import os
from typing import Listdef 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. 类型转换工具函数
# env_utils.py
import osdef get_env_bool(key: str, default: bool = False) -> bool:value = os.getenv(key, '').lower()if value in ('true', '1', 'yes', 'on'):return Trueelif value in ('false', '0', 'no', 'off'):return Falsereturn defaultdef get_env_int(key: str, default: int = 0) -> int:try:return int(os.getenv(key, default))except (ValueError, TypeError):return defaultdef 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. 安全处理敏感信息
# security_utils.py
import os
from cryptography.fernet import Fernetclass 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 valuedef 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
# 环境变量文件
.env
.env.*
!.env.example# 敏感信息
*.key
*.pem
*.cert# 日志和临时文件
logs/
tmp/
环境模板文件 (.env.example)
# 复制此文件为 .env 并填写实际值
BASE_URL=https://api.example.com
API_KEY=your_api_key_here
API_SECRET=your_api_secret_hereBROWSER=chrome
HEADLESS=false
TIMEOUT=30DB_HOST=localhost
DB_PORT=5432
DB_NAME=your_database
DB_USER=your_username
DB_PASSWORD=your_password
🎯 总结优势
-
安全性:敏感信息不进入代码仓库
-
灵活性:一套代码适应多环境
-
可维护性:配置集中管理,易于修改
-
协作友好:团队协作时各自维护本地配置
-
自动化友好:CI/CD流水线中容易注入环境变量
通过合理使用环境变量,可以构建出更加健壮、安全和灵活的自动化测试框架。