SDET / SWE · Technical Fundamentals

TikTok Python 面向对象:封装、继承与多态如何落到测试设计

从状态边界和可替换接口解释三特征,区分继承与组合,避免把私有命名当安全隔离。

题目重点:从状态边界和可替换接口解释三特征,区分继承与组合,避免把私有命名当安全隔离。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 讨论Python 3对象模型与业务设计,不承诺所有实现底层布局相同。
  • 用支付测试适配器作虚构练习案例,不代表指定框架。

解题路线

  1. 封装是让对象维护自身不变量并通过明确接口修改状态,例如Payment的金额、币种和状态转换不能任意改写;仅把字段放进class并不自动保证业务约束。
  2. Python单下划线是非公共命名约定,双下划线触发名称改写以减少子类冲突;都不是阻止恶意访问的安全权限。敏感凭证访问仍需真实授权与隔离。
  3. 继承表达子类型关系:子对象应在父接口的预期合同下可替换。若子类加强输入前提或悄悄改变返回/异常语义,调用方测试会被破坏,不能只检查isinstance。
  4. 多态可以通过同名协议实现,不必共享父类。两个适配器都有charge/refund接口,测试服务只依赖协议;duck typing要配合接口合同、类型检查或契约测试,避免误把同名当同义。
  5. 组合适合“使用某能力”:支付服务持有gateway而非继承某云支付客户端,能注入fake并单测状态机。继承用于稳定可替换层级,避免多层层级牵动所有测试。
  6. 回答时连接测试风险:验证对象边界、覆盖子类型相同合同、用依赖注入控制外部副作用;不要仅背三词而没有实际设计判断。

手动走一遍

Dog.speak返回woof,Robot.speak返回beep;列表中的对象均可调用speak,展示协议多态。业务上同理,fake gateway与真实gateway应遵守相同成功/失败合同,fake不能总成功而遮住异常路径。

规模与取舍

设计原则没有统一运行复杂度;协议分派成本不是测试总耗时主因,外部IO与数据规模另测。组合可缩小单测依赖,不保证必然减少运行时间。

易错点与追问

容易失分的边界

  • 把双下划线当访问权限。
  • 为复用几行代码建立不满足可替换性的继承。
  • fake只覆盖成功路径。

继续深挖

  • 抽象基类与结构协议怎样选?
  • 子类改变异常类型如何发现?
  • 测试对象不变量应放在哪层?

技术参考

✓已复制微信号!