测试面试精要

一、测试基础与理论

1. 软件测试的核心原则和分类有哪些?

  • 核心原则
    1. 测试显示缺陷的存在:测试只能证明软件存在缺陷,不能证明没有缺陷。
    2. 穷尽测试是不可能的:输入空间和路径组合庞大,需采用等价类和边界值等方法。
    3. 测试尽早介入:缺陷发现越早,修复成本越低。
    4. 缺陷集群性(二八定律):80%的缺陷集中在20%的模块中。
    5. 杀虫剂悖论:重复执行相同用例会发现越来越少的新缺陷,需定期更新用例。
    6. 测试活动依赖于测试内容:不同项目(如嵌入式、Web)测试策略不同。
  • 分类
    • 按阶段:单元测试、集成测试、系统测试、验收测试。
    • 按技术:黑盒测试(功能)、白盒测试(代码逻辑)、灰盒测试(接口/数据流)。
    • 按内容:功能测试、性能测试、安全测试、兼容性测试、回归测试等。

2. 测试用例的核心要素是什么?
一个标准的测试用例通常包含以下八大要素:

  1. 用例编号:唯一标识(如 Login-001)。
  2. 测试模块:所属功能模块(如用户登录)。
  3. 测试标题:简明描述测试目的(如验证正确账号密码登录成功)。
  4. 前置条件:执行前需满足的环境或状态(如已注册账号、网络正常)。
  5. 测试输入/步骤:具体操作步骤和数据。
  6. 预期结果:执行后应出现的正确结果(需具体、可验证)。
  7. 优先级:高/中/低,用于资源有限时排序。
  8. 测试类型:功能、边界、异常等。

3. 软件测试的完整流程是什么?

  1. 需求分析与测试计划:理解需求,制定测试策略、范围、资源和进度。
  2. 测试设计:设计测试用例,准备测试数据和脚本。
  3. 环境搭建:配置硬件、软件、网络及测试数据。
  4. 测试执行:执行用例,记录结果,提交缺陷。
  5. 缺陷跟踪:开发修复后回归验证。
  6. 测试总结与报告:输出覆盖率、缺陷统计、风险评估等报告。

4. 什么是缺陷生命周期?
缺陷从被发现到关闭的全过程,常见状态流转如下:

  • 新建(New) -> 分配(Assigned) -> 打开(Open) -> 修复(Fixed) -> 验证(Verify) -> 关闭(Closed)
  • 中间可能状态:重新打开(Reopen)(修复不通过)、拒绝(Rejected)(非缺陷)、延期(Deferred)(暂不修复)、重复(Duplicate)

5. 敏捷测试与传统测试的区别是什么?如何适应敏捷开发流程?

  • 区别
    • 周期:传统测试周期长(月/季),敏捷测试短(天/迭代)。
    • 介入时机:传统测试在开发后介入,敏捷测试从需求阶段即介入(测试左移)。
    • 角色:传统测试专职QA,敏捷测试强调全员测试(开发、产品均参与)。
    • 计划性:传统测试计划固定,敏捷测试计划灵活调整。
    • 自动化:传统测试鼓励自动化,敏捷测试依赖自动化(CI/CD基础)。
  • 适应方法
    • 参与User Story拆解,定义验收标准。
    • 持续集成(CI)中嵌入自动化测试。
    • 采用TDD(测试驱动开发)或BDD(行为驱动开发)。
    • 缩短反馈环,每个迭代都进行测试。

二、功能与接口测试

1. 功能测试中如何设计全面的测试用例,覆盖核心业务场景和异常场景?

  • 核心方法
    • 等价类划分:将输入分为有效/无效类。
    • 边界值分析:测试最小值、最大值、略超边界值。
    • 决策表/因果图:处理多条件组合逻辑。
    • 场景法:模拟用户实际业务流程(正常流、异常流)。
    • 错误推测:基于经验推测易错点。
  • 覆盖策略
    • 核心业务:主流程必测(如注册->登录->下单->支付)。
    • 异常场景:网络中断、数据为空、权限不足、输入非法字符等。
    • 兼容性:不同浏览器、设备、分辨率。

2. 接口测试的核心流程是什么?如何分析接口文档(API文档)?

  • 核心流程
    1. 分析文档:明确URL、Method、Headers、Params/Body、Response、Status Code。
    2. 设计用例:覆盖正常、异常、边界、安全场景。
    3. 执行测试:使用工具(Postman/SoapUI/JMeter)发送请求。
    4. 断言验证:校验状态码、响应体、数据库数据。
    5. 提交缺陷:记录问题并跟踪。
    6. 输出报告
  • 文档分析要点
    • 接口地址:完整URL(含域名、路径、端口)。
    • 请求方法:GET/POST/PUT/DELETE等。
    • 请求头:Content-Type、Authorization等。
    • 请求参数:必填/选填、类型、长度、枚举值。
    • 响应体:字段含义、类型、示例值。
    • 错误码:各状态码对应含义(如400参数错误,401未授权)。

3. HTTP/HTTPS协议的核心知识点?GET和POST请求的区别,常见状态码含义?

  • 核心知识点
    • HTTP是无状态、应用层协议,基于请求-响应模型。
    • HTTPS是HTTP over SSL/TLS,提供加密和身份认证。
    • 请求结构:请求行(Method URL Protocol)、请求头(Headers)、请求体(Body)。
    • 响应结构:状态行(Protocol StatusCode ReasonPhrase)、响应头、响应体。
  • GET vs POST
    特性 GET POST
    数据位置 URL参数(Query String) 请求体(Body)
    数据长度 有限制(通常2KB-8KB) 无限制(理论上)
    安全性 较低(明文暴露) 较高(Body不显示在URL)
    幂等性 是(多次执行结果相同) 否(可能产生副作用)
    缓存 通常可缓存 通常不缓存
    用途 查询数据 提交/修改数据
  • 常见状态码
    • 1xx:信息性(如100 Continue)。
    • 2xx:成功(200 OK, 201 Created, 204 No Content)。
    • 3xx:重定向(301永久移动, 302临时移动)。
    • 4xx:客户端错误(400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found)。
    • 5xx:服务器错误(500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable)。

4. 如何使用Postman/SoapUI进行接口测试?

  • Postman
    • 创建Collection组织接口。
    • 设置请求方法、URL、Headers、Body(form-data, raw-JSON等)。
    • 使用Environment管理变量(如baseURL、token)。
    • 编写Tests脚本进行断言(pm.test, pm.response.to.have.status(200))。
    • 使用Runner进行批量执行和生成报告。
  • SoapUI
    • 适用于SOAP和REST接口。
    • 导入WSDL文件或手动创建REST请求。
    • 设置Request Properties(参数、Headers)。
    • 使用Assertions(XPath, Contains, Schema Validation)验证响应。
    • 支持Security测试(WS-Security)。

5. 接口测试中如何处理依赖接口、鉴权接口(Token/Session)?

  • 处理依赖接口
    • 参数关联:前一个接口的响应数据(如用户ID、订单号)作为后一个接口的请求参数。
    • 方法:在Postman中使用pm.environment.set("var_name", value)存储变量,后接口用{{var_name}}引用;或使用Pre-request Script动态获取。
  • 处理鉴权
    • Token/Session:先调用登录接口获取Token,存入环境变量,后续请求在Headers中添加Authorization: Bearer {{token}}
    • Cookie:浏览器登录后导出Cookie填入Postman Headers,或使用Postman的Cookie管理器自动管理。
    • OAuth2.0:按流程获取Access Token,配置到请求头。

三、自动化测试

1. 自动化测试的适用场景是什么?如何选择自动化测试工具和框架?

  • 适用场景
    • 回归测试:版本迭代后快速验证核心功能。
    • 冒烟测试:每日构建后快速验证系统可用性。
    • 数据驱动测试:大量重复数据输入。
    • 高频执行:如性能压测、持续集成流水线。
    • 不适合:UI频繁变动、一次性测试、探索性测试。
  • 选择工具/框架
    • Web UI:Selenium(支持多语言)、Cypress、Playwright。
    • API:Postman(轻量)、RestAssured(Java)、Requests(Python)、JMeter(性能+功能)。
    • Mobile:Appium(跨平台)。
    • 选择依据:项目技术栈、团队技能、维护成本、社区支持、CI/CD集成能力。

2. Selenium的核心原理是什么?如何实现元素定位、iframe切换、等待机制?

  • 核心原理
    • Selenium WebDriver通过浏览器驱动(如ChromeDriver)与浏览器通信。
    • 发送HTTP请求(JSON Wire Protocol)控制浏览器执行操作(点击、输入、获取元素等)。
    • 浏览器返回执行结果(DOM、截图、日志等)。
  • 元素定位
    • 使用By类:ID, NAME, CLASS_NAME, TAG_NAME, LINK_TEXT, PARTIAL_LINK_TEXT, CSS_SELECTOR, XPATH
    • 示例:driver.find_element(By.ID, "username")
  • iframe切换
    • driver.switch_to.frame("frame_name_or_id")driver.switch_to.frame(0)(索引)。
    • 操作完后切回主文档:driver.switch_to.default_content()
  • 等待机制
    • 强制等待time.sleep(5)(不推荐,阻塞线程)。
    • 隐式等待driver.implicitly_wait(10)(全局查找元素等待时间)。
    • 显式等待(推荐):WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "username"))),针对特定条件等待。

3. Python/Java在自动化测试中的应用?如何编写可维护的自动化测试脚本?

  • 应用
    • Python:语法简洁,生态丰富(pytest, unittest, requests, BeautifulSoup),适合快速脚本和小型项目。
    • Java:强类型、面向对象,适合大型企业级项目(TestNG, JUnit, Selenium WebDriver),与开发代码风格一致,便于维护。
  • 编写可维护脚本
    • Page Object Model (POM):将页面元素和操作封装成类,测试用例调用页面类,降低耦合。
    • 模块化:将重复代码(如登录、数据准备)封装成函数或基类。
    • 使用配置文件:将URL、账号、环境参数放在config文件中。
    • 日志与报告:集成logging模块和Allure/ExtentReports生成详细报告。
    • 命名规范:变量、函数、类名见名知意。
    • 异常处理:捕获异常并记录,避免脚本崩溃。

4. App自动化测试(Appium)的环境搭建和核心操作?

  • 环境搭建
    1. 安装Node.js、JDK、Android SDK(或Xcode for iOS)。
    2. 安装Appium:npm install -g appium
    3. 安装Appium Desktop(图形化工具)。
    4. 配置环境变量(ANDROID_HOME, PATH)。
    5. 连接设备或启动模拟器:adb devices
    6. 安装Python客户端:pip install Appium-Python-Client
  • 核心操作
    • Desired Capabilities:配置设备名、平台、包名、活动名等。
      desired_caps = {
          "platformName": "Android",
          "deviceName": "emulator-5554",
          "appPackage": "com.example.app",
          "appActivity": ".MainActivity"
      }
      
    • 启动会话driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
    • 元素定位:同Selenium(find_element(By.ID, ...))。
    • 手势操作:滑动、点击、长按、输入文本。
    • 关闭会话driver.quit()

5. 自动化测试报告如何生成?如何处理自动化脚本的稳定性问题?

  • 报告生成
    • Pytestpytest --html=report.htmlpytest --alluredir=allure-results,配合Allure生成精美报告。
    • JUnit/TestNG:内置XML报告,可转换为HTML。
    • ExtentReports:Java中常用,支持图表、截图。
    • Allure:跨语言,支持步骤、附件、趋势图。
  • 处理稳定性问题
    • 显式等待:避免time.sleep,使用WebDriverWait
    • 元素定位优化:使用稳定ID、CSS Selector,避免动态属性。
    • 重试机制:对偶发失败用例设置重试(如pytest-rerunfailures)。
    • 环境隔离:使用Docker容器化测试环境,确保一致性。
    • 日志监控:记录详细日志,便于定位失败原因。
    • CI/CD集成:在Jenkins/GitLab CI中并行执行,失败时及时通知。

四、性能与安全测试

1. 性能测试的核心指标有哪些?

  • 响应时间(Response Time):从请求发出到收到响应的时间(平均、最小、最大、90%/95%/99%分位)。
  • 吞吐量(Throughput/TPS/QPS):单位时间内处理的请求数。
  • 并发用户数(Concurrent Users):同时在线或操作的用户数。
  • 资源利用率:CPU、内存、磁盘IO、网络带宽占用率。
  • 错误率(Error Rate):失败请求占总请求的比例。
  • 点击率(Hits per Second):每秒点击次数(常用于Web服务器)。

2. Jmeter/LoadRunner的使用流程?如何设计性能测试场景(单接口压测、混合场景)?

  • 使用流程
    1. 需求分析:确定目标(如TPS>100,响应<2s)。
    2. 脚本录制/编写:使用JMeter的HTTP Proxy Server录制,或LoadRunner的VuGen录制;也可手动编写。
    3. 参数化:替换硬编码数据为变量(CSV Data Set Config)。
    4. 添加断言:验证响应内容。
    5. 配置监听器:聚合报告、图形结果、响应时间图。
    6. 场景设计:设置并发数、持续时间、启动/停止策略。
    7. 执行测试:监控服务器资源。
    8. 分析结果:定位瓶颈(数据库、CPU、网络等)。
  • 场景设计
    • 单接口压测:固定参数,阶梯式增加并发(如10->50->100->500),观察TPS和响应时间变化。
    • 混合场景:按业务比例分配并发(如登录20%、查询50%、下单30%),使用线程组或LoadRunner的Controller配置不同脚本的混合执行。

3. 性能瓶颈常见于哪些环节?(服务器、数据库、网络、代码)如何分析和优化?

  • 常见环节
    • 服务器:CPU过载、内存不足、磁盘IO瓶颈、线程池耗尽。
    • 数据库:慢查询、锁竞争、连接池耗尽、索引缺失。
    • 网络:带宽不足、延迟高、丢包。
    • 代码:算法低效、死循环、资源未释放、同步阻塞。
  • 分析与优化
    • 监控工具:服务器(top, vmstat, iostat)、数据库(慢查询日志、EXPLAIN)、网络(ping, traceroute, Wireshark)。
    • 优化措施
      • 服务器:扩容、优化线程模型、负载均衡。
      • 数据库:加索引、优化SQL、分库分表、读写分离。
      • 网络:压缩数据、CDN加速、优化路由。
      • 代码:算法优化、异步处理、缓存(Redis)、减少I/O。

4. 常见的安全漏洞有哪些?如何进行基础安全测试?

  • 常见漏洞
    • 注入攻击:SQL注入、命令注入。
    • 跨站脚本(XSS):存储型、反射型、DOM型。
    • 跨站请求伪造(CSRF)
    • 认证与会话管理缺陷:弱密码、Session固定、Token泄露。
    • 敏感数据泄露:明文传输、未加密存储。
    • 访问控制缺失:越权访问(垂直/水平)。
    • 安全配置错误:默认配置、目录遍历。
  • 基础安全测试
    • SQL注入:在输入框输入' OR '1'='1看是否绕过登录或返回异常数据。
    • XSS:输入<script>alert('xss')</script>看是否弹窗。
    • 越权:修改URL参数(如user_id=1改为user_id=2)看是否能访问他人数据。
    • 敏感信息:检查URL、Response中是否暴露密码、Token、身份证号等。
    • 目录遍历:尝试访问../看是否能读取系统文件。

5. Burp Suite的核心功能?如何进行漏洞扫描和渗透测试入门?

  • 核心功能
    • Proxy:拦截、修改、重放HTTP/HTTPS请求。
    • Scanner:自动扫描常见漏洞(需专业版)。
    • Intruder:自动化攻击(爆破、模糊测试)。
    • Repeater:手动重放请求,修改参数调试。
    • Sequencer:分析会话令牌随机性。
    • Decoder/Encoder:编解码数据。
  • 入门渗透测试
    1. 配置浏览器代理指向Burp Proxy。
    2. 启用Intercept,捕获登录请求。
    3. 使用Repeater修改参数(如用户名)重放,观察响应。
    4. 使用Intruder对登录接口进行字典爆破(设置Payload)。
    5. 使用Scanner扫描目标站点(需授权)。
    6. 结合SQLMap进行SQL注入测试。
    7. 学习OWASP Top 10漏洞原理和利用方法。

五、数据库与Linux

1. MySQL的基础查询语句?如何进行多表关联查询、聚合函数使用?

  • 基础查询
    • SELECT * FROM table_name; — 查询所有。
    • SELECT column1, column2 FROM table_name WHERE condition; — 条件查询。
    • INSERT INTO table_name (col1, col2) VALUES ('val1', 'val2'); — 插入。
    • UPDATE table_name SET col1='val1' WHERE condition; — 更新。
    • DELETE FROM table_name WHERE condition; — 删除。
  • 多表关联查询
    • INNER JOIN:返回两表匹配的行。
      SELECT a.name, b.order_id FROM users a INNER JOIN orders b ON a.id = b.user_id;
      
    • LEFT JOIN:返回左表所有行,右表匹配不到为NULL。
    • RIGHT JOIN:返回右表所有行。
    • UNION:合并两个查询结果(去重)。
  • 聚合函数
    • COUNT(*), SUM(column), AVG(column), MAX(column), MIN(column)
    • 配合GROUP BY分组:
      SELECT user_id, COUNT(*) as order_count FROM orders GROUP BY user_id;
      

2. 如何通过SQL语句排查线上问题?

  • 常见排查场景
    • 慢查询:开启慢查询日志,使用EXPLAIN分析SQL执行计划(关注type, key, rows)。
    • 数据异常SELECT * FROM table WHERE condition LIMIT 10; 查看具体数据。
    • 死锁:查看SHOW ENGINE INNODB STATUS; 获取死锁信息。
    • 连接数过多SHOW PROCESSLIST; 查看当前连接。
    • 数据不一致:对比不同表或字段,使用JOINUNION找出差异。
    • 权限问题SHOW GRANTS FOR user; 检查权限。

3. Linux的常用命令有哪些?(文件操作、日志查看、进程管理:ls/cd/grep/tail/ps)

  • 文件操作
    • ls -la:列出所有文件(含隐藏)。
    • cd /path/to/dir:切换目录。
    • cp source dest:复制。
    • mv source dest:移动/重命名。
    • rm file:删除文件。
    • touch file:创建空文件。
    • mkdir dir:创建目录。
  • 日志查看
    • tail -f /var/log/syslog:实时查看日志尾部。
    • grep "error" /var/log/app.log:搜索包含”error”的行。
    • less /var/log/app.log:分页查看大文件。
  • 进程管理
    • ps aux:查看所有进程。
    • top / htop:实时查看进程资源占用。
    • kill -9 PID:强制杀死进程。
    • pgrep process_name:查找进程PID。

4. 如何在Linux环境下部署测试环境、查看应用日志?

  • 部署测试环境
    1. 安装依赖:如Java、MySQL、Nginx、Docker。
    2. 上传应用包(如.jar, .war, Docker镜像)。
    3. 配置环境变量、配置文件(application.yml)。
    4. 启动应用:java -jar app.jardocker run -d image_name
    5. 配置反向代理(Nginx)指向应用端口。
    6. 验证:访问http://server_ip:port
  • 查看应用日志
    • 若应用输出到控制台:nohup java -jar app.jar > app.log 2>&1 &,然后用tail -f app.log
    • 若写入文件:tail -f /path/to/logs/app.log
    • 使用grep过滤:grep "ERROR" app.log
    • 使用less分页:less app.log,支持上下翻页、搜索。

5. 如何使用Navicat/命令行进行数据库备份与恢复?

  • Navicat
    • 备份:右键数据库 -> 转储SQL文件 -> 结构和数据。
    • 恢复:右键数据库 -> 运行SQL文件 -> 选择备份文件。
  • 命令行(mysqldump)
    • 备份
      mysqldump -u username -p database_name > backup.sql
      
    • 恢复
      mysql -u username -p database_name < backup.sql
      
    • 定时备份:配合crontab设置定时任务。

上一篇
下一篇