← Fannie Mae Interview Insights

Fannie Mae·Data Scientist·Technical Phone Screen·Senior

SeniorPrefer not to say
May 2026

Summary

Technical interview for a Data Scientist role at Fannie Mae that ended up being way more frontend/QA-architecture heavy than I expected. Two big parts: a conceptual breakdown of UI vs backend testing across a full test pyramid, then a deep-dive test matrix for a promo code feature. Not your typical data science interview.

Questions Asked (6)

Q1

For a single-page app backed by a BFF that calls a payment API, how do you decide what belongs in UI tests versus backend tests, and which layers do you mock at each level of the test pyramid?

System DesignTechnical Trade-offsAPI & Integrations
Author's notes

This one sprawled fast.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the goal of each test layer: UI tests validate user-facing behavior and integration, while backend tests validate business logic and data integrity. Then map the test pyramid to the SPA-BFF-payment API architecture, specifying what to mock at each level (e.g., mock payment API in BFF tests, mock BFF in UI tests). Emphasize risk-based testing and the trade-offs between speed, cost, and confidence.

Pro tip: Highlight that payment flows are high-risk, so you should have a few end-to-end tests that hit a sandbox payment API, but keep them minimal to avoid flakiness and cost. Also, mention contract testing (e.g., Pact) to ensure the BFF and payment API stay in sync without full integration tests.

1. Define test objectives per layer

Clarify that UI tests verify user interactions and rendering, while backend tests verify business rules, data transformations, and API contracts. This prevents overlap and ensures each layer tests what it's best at.

2. Map the architecture to the test pyramid

Identify the components: SPA (UI), BFF (backend-for-frontend), and payment API. Allocate tests: many unit tests for BFF logic, some integration tests for BFF-payment API, and few UI tests for critical user journeys.

3. Decide mocking strategy per layer

In UI tests, mock the BFF to isolate UI behavior; in BFF unit tests, mock the payment API client; in BFF integration tests, use a sandbox or mock server for the payment API. Avoid mocking the BFF in integration tests unless testing error handling.

4. Apply risk-based prioritization

Focus more tests on high-risk areas like payment processing, authentication, and error handling. Use fewer end-to-end tests for critical paths (e.g., successful payment) and rely on lower-level tests for edge cases.

5. Address trade-offs and maintenance

Discuss how mocking reduces flakiness and speed but can miss integration issues. Recommend contract testing to validate BFF-payment API interactions without full E2E. Balance test coverage with maintenance cost.

Key Points to Mention

  • Test pyramid principles: many unit tests, fewer integration, minimal E2E
  • Mocking the BFF in UI tests to isolate frontend logic
  • Mocking the payment API in BFF unit tests using stubs or mocks
  • Using sandbox environments or service virtualization for BFF integration tests
  • Contract testing (e.g., Pact) to ensure BFF and payment API compatibility
  • Risk-based testing: prioritize payment flows and error scenarios

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

How do you prevent flaky tests caused by network instability, timing issues, and async behavior, and how do you detect regressions using test oracles, golden images, or contract tests?

Technical Trade-offsRoot Cause Analysis
Author's notes

Talked about deterministic time injection and intercepting network calls at the boundary.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging that flaky tests stem from non-determinism, then describe a layered strategy: isolate and control external dependencies (e.g., mock network calls, use deterministic clocks), and apply robust synchronization patterns for async code. For regression detection, explain how you select and combine test oracles, golden images, and contract tests based on data and model characteristics, emphasizing trade-offs in maintenance and false positives.

Pro tip: Frame flakiness as a signal of hidden system fragility, not just a test problem—show how you use flaky test metrics to drive architectural improvements and set realistic SLAs for test reliability.

1. Identify and categorize sources of flakiness

Break down flakiness into network, timing, and async causes, and instrument tests to capture failure patterns (e.g., retries, timeouts, race conditions).

2. Stabilize tests through isolation and control

Use mocking, stubbing, and dependency injection for network calls; employ fake clocks and deterministic scheduling for timing; and apply proper async patterns like polling with backoff or event-driven waits.

3. Choose appropriate test oracles for regression detection

Select oracles based on data type and model output: exact assertions for deterministic outputs, tolerance-based checks for numerical results, and statistical tests for stochastic models.

4. Leverage golden images and contract tests strategically

Use golden images for visual or high-dimensional outputs with versioning and diff thresholds; use contract tests to validate interfaces between services and data pipelines, ensuring backward compatibility.

5. Monitor, iterate, and balance trade-offs

Track flaky test rates and regression detection metrics, and adjust strategies to balance test reliability, maintenance cost, and coverage—especially in regulated environments like Fannie Mae.

Key Points to Mention

  • Mocking and service virtualization to eliminate network dependencies in unit and integration tests
  • Deterministic time and async handling: fake clocks, event loops, and avoiding sleep-based waits
  • Test oracles: exact vs. approximate assertions, statistical tests for model outputs, and handling non-determinism
  • Golden image testing: versioning, diff thresholds, and update strategies to avoid false positives
  • Contract testing (e.g., Pact) for microservices and data contracts to catch breaking changes early
  • Trade-offs: test flakiness vs. coverage, maintenance overhead, and the cost of false positives in a regulated financial context

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

Where do security checks like XSS, CSRF, and authorization validation belong in the test layers, and how do you enforce idempotency when retries happen?

API & IntegrationsTechnical Trade-offsSystem Design
Author's notes

Honestly placed XSS checks in component tests and CSRF at integration level and they pushed back a little.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by mapping security checks to the test pyramid: unit tests for input validation and authorization logic, integration tests for CSRF tokens and XSS sanitization across components, and end-to-end tests for full attack scenarios. Then explain idempotency enforcement through idempotency keys, deduplication, and transactional guarantees, emphasizing retry-safe design.

Pro tip: In regulated environments like Fannie Mae, tie security and idempotency to compliance and auditability—show you understand that these aren't just technical concerns but risk management requirements.

1. Map security checks to test layers

Place input validation and authorization logic in unit tests, CSRF/XSS protections in integration tests, and full attack simulations in end-to-end tests. This ensures fast feedback and comprehensive coverage.

2. Define idempotency requirements

Identify operations that must be idempotent (e.g., payments, data updates) and specify expected behavior under retries, including duplicate detection and state consistency.

3. Implement idempotency mechanisms

Use idempotency keys, request deduplication, and transactional outbox patterns to ensure repeated requests don't cause unintended side effects.

4. Test idempotency under retries

Write tests that simulate network failures, timeouts, and duplicate requests to verify idempotency guarantees and error handling.

5. Monitor and audit in production

Log idempotency key usage and security events, and set up alerts for anomalies to maintain compliance and detect issues early.

Key Points to Mention

  • Test pyramid: unit, integration, and end-to-end tests for security checks
  • OWASP Top 10: XSS and CSRF prevention techniques (e.g., output encoding, anti-CSRF tokens)
  • Authorization validation at multiple layers: API gateway, service, and data access
  • Idempotency keys and deduplication strategies for retry-safe APIs
  • Transactional guarantees and exactly-once processing semantics
  • Compliance and auditability requirements in financial systems

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

How do you measure test coverage beyond line or branch coverage, specifically around requirements coverage, risk coverage, and data coverage?

Product Analytics & MetricsTechnical Trade-offs
Author's notes

Short answer from me: requirements traceability matrix, risk-weighted test prioritization, and equivalence partitioning for data.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging that line/branch coverage is necessary but insufficient, then structure your answer around three dimensions: requirements, risk, and data. For each, describe specific metrics and techniques you've used, and tie them to business impact—especially in a regulated domain like mortgage finance where model risk management and data integrity are critical.

Pro tip: Emphasize that coverage should be tied to business risk and model validation standards (e.g., SR 11-7), not just code. Mention that you prioritize coverage where errors would have the highest financial or compliance impact.

1. Requirements Coverage

Map each requirement to test cases using a traceability matrix, and measure the percentage of requirements with at least one test. Include edge cases and negative scenarios derived from business rules.

2. Risk Coverage

Identify high-risk areas (e.g., data quality, model assumptions, regulatory compliance) and assign risk scores. Measure the proportion of high-risk scenarios covered by tests, and track residual risk.

3. Data Coverage

Assess coverage across data dimensions: schema, value distributions, missingness, outliers, and time periods. Use techniques like data profiling and partition testing to ensure representative data is used.

4. Combine Metrics into a Dashboard

Aggregate these coverage metrics into a dashboard that shows overall coverage health and highlights gaps. Use thresholds to trigger reviews or additional testing.

5. Iterate and Prioritize

Use the coverage insights to prioritize testing efforts based on risk and business impact. Continuously refine coverage criteria as the model and data evolve.

Key Points to Mention

  • Traceability matrix linking requirements to test cases
  • Risk-based testing prioritization (e.g., FMEA, risk matrices)
  • Data profiling and partition coverage (e.g., equivalence partitioning, boundary value analysis)
  • Coverage of edge cases and negative scenarios
  • Regulatory and compliance considerations (e.g., SR 11-7, fair lending)
  • Automated tools for coverage measurement (e.g., pytest-cov, custom scripts)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

Design a test matrix for a new promo code field on a checkout page. The code is validated asynchronously via the BFF, updates the order total, persists the promo, and fires an analytics event. Cover functional, boundary, accessibility, cross-compatibility, resilience, contract, and analytics scenarios.

A/B Testing & ExperimentationAPI & IntegrationsSystem Design
Author's notes

This was the bulk of the interview and where I felt most exposed.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the scope and assumptions, then structure your answer around the seven required categories, ensuring each includes specific test cases. Emphasize how you would prioritize tests based on risk and business impact, and tie your approach to data science principles like experimentation and metrics validation.

Pro tip: Frame your test matrix around user journeys and failure modes, and explicitly mention how you would measure the success of the promo code feature using A/B testing and analytics. This shows you think beyond QA and understand the data science implications.

1. Clarify Requirements and Assumptions

Ask clarifying questions about the promo code rules, BFF behavior, analytics event schema, and target platforms. State your assumptions to ensure alignment before diving into test design.

2. Define Test Categories and Scope

Outline the seven categories (functional, boundary, accessibility, cross-compatibility, resilience, contract, analytics) and briefly explain what each entails for this feature.

3. Generate Specific Test Cases per Category

For each category, list concrete test scenarios, covering positive/negative paths, edge cases, and failure modes. Include data validation, UI behavior, and integration points.

4. Prioritize and Organize the Matrix

Group tests by priority (e.g., critical, high, medium) based on risk and business impact. Suggest a format (e.g., table) for the matrix and mention automation opportunities.

5. Incorporate Data Science Perspective

Explain how you would validate the analytics event and use A/B testing to measure the promo code's impact on conversion and order value. Mention metrics, sample size, and statistical significance.

Key Points to Mention

  • Asynchronous validation: test loading states, timeouts, and race conditions with BFF responses.
  • Boundary testing: promo code length, special characters, case sensitivity, expiration dates, and usage limits.
  • Accessibility: ensure the field is screen-reader friendly, has proper labels, error announcements, and keyboard navigation.
  • Cross-compatibility: test across browsers, devices, and OS; consider responsive design and input methods.
  • Resilience: simulate BFF failures, network latency, and retry logic; ensure graceful degradation and user feedback.
  • Contract testing: verify BFF API request/response schemas, error codes, and analytics event payloads match specifications.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q6

For the promo code feature, how do you test resilience scenarios like offline mode, server timeouts, 429 rate limits, and 5xx errors, and how do you ensure the UI eventually reflects server truth after stale state?

API & IntegrationsTechnical Trade-offsRoot Cause Analysis
Author's notes

Talked about stubbing the BFF at the component level for 429 and 5xx, and using service workers or network interception for offline.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by outlining a layered testing strategy that covers unit, integration, and end-to-end tests for each failure mode, then explain how you simulate these conditions using tools like network throttling, mock servers, and fault injection. Emphasize that the UI should handle errors gracefully and eventually reconcile with server truth through retries, idempotency, and state synchronization mechanisms.

Pro tip: Demonstrate maturity by discussing how you prioritize failure scenarios based on business impact and how you balance resilience with user experience—for example, showing a cached promo code with a clear 'last updated' timestamp rather than blocking the UI.

1. Identify failure modes and define expected behavior

Enumerate each scenario (offline, timeout, 429, 5xx) and specify how the system should behave: e.g., offline should use cached data with an indicator, timeouts should trigger retries with backoff, 429 should respect Retry-After, and 5xx should fall back to stale data or show an error.

2. Simulate failures in test environments

Use tools like Charles Proxy, Toxiproxy, or custom mock servers to inject latency, drop connections, return 429/5xx, and simulate offline mode. For unit tests, mock API clients to throw specific errors.

3. Validate UI behavior and state management

Write integration and E2E tests (e.g., with Cypress or Playwright) that assert the UI shows appropriate messages, disables actions, and retries automatically. Verify that stale state is eventually replaced when the server recovers.

4. Implement reconciliation and conflict resolution

Ensure the client periodically polls or uses push updates to fetch server truth. Use versioning or timestamps to detect stale data and resolve conflicts, and make promo code application idempotent to avoid double-application.

5. Monitor and iterate in production

Set up logging and alerts for these failure modes, track metrics like retry counts and stale data age, and use feature flags to roll out resilience improvements gradually.

Key Points to Mention

  • Idempotency keys for promo code application to prevent duplicate redemptions during retries.
  • Exponential backoff with jitter for retries on 429 and 5xx errors, respecting Retry-After headers.
  • Caching strategies (e.g., stale-while-revalidate) to serve promo codes offline while indicating data freshness.
  • Optimistic UI updates with rollback on failure, and eventual consistency via background sync.
  • Testing tools: network throttling in Chrome DevTools, mock servers (e.g., WireMock), and contract testing.
  • Observability: logging error rates, retry attempts, and time-to-reconcile to measure resilience.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.