DEV Community

Cover image for How to Audit a Mobile App Development Company: An Engineering Manager's Playbook
Charles Wade
Charles Wade

Posted on

How to Audit a Mobile App Development Company: An Engineering Manager's Playbook

A few years back I sat in on a vendor pitch that had everything - polished slides, a confident VP walking through "agile delivery," a slide titled "quality-first culture" with a checkmark icon next to it. Six months later I was the one staring at the codebase they'd handed off, and it was not a pleasant afternoon. That gap between what a deck promises and what actually lands in your repo is the whole reason this article exists.

Somewhere in my fifteenth or so year of doing this work, I stopped putting much stock in the sales conversation and started asking to see the repo instead. If you're currently sizing up a mobile app development company for a real engagement, that's the shift worth making before you sign anything, not after the first sprint goes sideways.

What follows isn't a checklist you read once and file away. It's more or less the process I actually run - built up over three decades of shipping software, working with vendors who delivered exactly what they said they would, and a handful who very much didn't. The failures taught me more than the successes did, honestly.

Why the Sales Conversation Tells You Almost Nothing

Sales engineers are good at their jobs, and that's precisely the problem. They're trained to answer the question you ask, not the one you should have asked. Ask "do you do CI/CD?" and the answer is always yes - it costs them nothing to say it. Ask instead, "walk me through your last production rollback, what triggered it, and how long the fix took," and you'll get something real. Assuming there's an answer at all.

I've come to treat technical due diligence less like an interview and more like reviewing the company the way you'd review a pull request. Their engineering culture leaves traces everywhere - in commit history, in how their docs are organized (or aren't), in how they respond when you ask something slightly uncomfortable. You just have to know where to look, and be willing to sit through a bit of awkward silence when the answer isn't ready.

What to Look for in an Enterprise Mobile App Development Company

Four things, in my experience, predict long-term delivery quality better than anything on a slide. None of them show up in a sales deck. All of them are things a legitimate team can show you without much notice.

1. Automated Test Coverage - Look at the Shape, Not the Percentage

Everyone will hand you a coverage number. I'd mostly ignore it. A team sitting at 90% coverage on getters and setters while their payment logic sits at 12% is in worse shape than a team honestly at 60%, concentrated where the risk actually lives.

What I ask for instead is a coverage report broken down by module, plus a sample test suite for something that actually branches - authentication, checkout, offline sync. Here's roughly the kind of thing I want to see from a Kotlin team:

class CheckoutViewModelTest {

    @Test
    fun `applies discount only when promo code is valid and not expired`() = runTest {
        val expiredPromo = PromoCode("SAVE10", expiry = yesterday())
        val result = checkoutViewModel.applyPromo(expiredPromo)

        assertEquals(CheckoutState.PromoRejected, result)
        assertEquals(0.0, checkoutViewModel.discountAmount.value)
    }

    @Test
    fun `retries payment gateway call up to 3 times on transient failure`() = runTest {
        coEvery { paymentGateway.charge(any()) } throws IOException() andThen success

        val result = checkoutViewModel.processPayment(order)

        coVerify(exactly = 2) { paymentGateway.charge(any()) }
        assertTrue(result.isSuccess)
    }
}
Enter fullscreen mode Exit fullscreen mode

If a team can pull up something like this without scrambling for twenty minutes first, their tests are lived-in - written because they got burned once, not written the week before a client demo. If they can't produce anything close to it, that tells you something too, even if nobody says it out loud.

Worth noting: the complexity of what you're building changes how much this matters. A team estimating something like the cost to build an app like Poshmark - with listings, in-app messaging, payments, and search all interacting - needs test coverage on the interactions between those systems, not just each one in isolation. That's usually where the real bugs live anyway.

2. Infrastructure-as-Code, or the Lack of It

I like to ask a blunt question here: "If your lead DevOps person quit tomorrow, could someone else stand up a staging environment from version control alone?"

A surprising number of agencies fail this outright. Their infrastructure lives in one engineer's head, loosely documented in a wiki page nobody's touched since sometime in 2023, running on servers that were configured by hand and that everyone's a little afraid to touch. I've inherited this exact situation twice. Both times, it cost the client months of quiet, invisible delay while we reverse-engineered something that should've already existed on paper - or rather, in code.

What you actually want sitting in their repo looks more like this - boring, version-controlled, unremarkable in the best possible sense:

# terraform/staging/main.tf
resource "aws_ecs_service" "mobile_api" {
  name            = "mobile-api-staging"
  cluster         = aws_ecs_cluster.staging.id
  task_definition = aws_ecs_task_definition.mobile_api.arn
  desired_count   = 2

  deployment_circuit_breaker {
    enable   = true
    rollback = true
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.mobile_api.arn
    container_name    = "mobile-api"
    container_port    = 8080
  }
}
Enter fullscreen mode Exit fullscreen mode

Notice the deployment_circuit_breaker block sitting in there. It's a small detail, but it usually means this is a team that's already had a bad rollout at 2am and built the safeguard in response, rather than a team still waiting for that lesson to arrive.

3. CI/CD Maturity - Ask to See It Run, Don't Just Take Their Word For It

There's a real gap between "we use CI/CD" and having a pipeline that actually gates merges on passing tests, runs static analysis, and ships builds without someone manually dragging a build through TestFlight at eleven at night. So I ask vendors to screen-share a recent pipeline run - not a sanitized case study, an actual one, mess included if there is any.

A pipeline that reflects genuine maturity tends to look something like this:

# .github/workflows/mobile-ci.yml
name: Mobile CI
on: [pull_request]

jobs:
  test-and-lint:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run unit tests
        run: bundle exec fastlane test
      - name: Static analysis
        run: swiftlint --strict
      - name: Check for hardcoded secrets
        run: trufflehog filesystem . --fail

  build-and-deploy:
    needs: test-and-lint
    if: github.ref == 'refs/heads/main'
    runs-on: macos-latest
    steps:
      - name: Build and upload to TestFlight
        run: bundle exec fastlane beta
Enter fullscreen mode Exit fullscreen mode

That trufflehog step in the middle isn't decoration. It leads straight into the part of the audit I actually care about most.

4. Security Practices - Where I Stop Being Polite

I've opened codebases with API keys committed directly into source control, just sitting there in the git history for anyone with repo access to find. I've seen auth tokens stored in plaintext SharedPreferences on Android, which - if you haven't worked in mobile day to day - is roughly like leaving your house key taped under the doormat with a sign pointing at it.

So by this point in the audit, I ask directly, no softening:

  • Do they run dependency scanning - Snyk, Dependabot, whatever - on every build, or only "when someone remembers to kick it off"?
  • Is there a documented secrets management approach, or does "documented" turn out to mean a Slack message from eighteen months ago that half the team has forgotten about?
  • Have they had a third-party penetration test in the last year, and will they share the summary findings? Not the full report necessarily - just the summary.
  • How do they handle certificate pinning and secure on-device storage?

A team that's serious about this space will answer all four specifically. A team that isn't will get vague, pivot to talking about their "security-first culture," and somehow never land on an actual practice. I've learned to trust that pivot more than almost any other signal in the whole process - it's rarely wrong.

Putting the Audit Together

None of these four checks should take more than an hour each if the vendor is legitimate. A real engineering team can pull up coverage numbers, Terraform state, a live pipeline run, and a security summary without much prep, because that material already exists and gets touched daily. It's not a performance staged for your benefit - it's just Tuesday for them.

If it takes a week to "assemble evidence" of practices they claim are already standard, you've learned what you needed to know before opening a single pull request.

This is also the point where I'd look past infrastructure and into what the team can actually build. If personalization or recommendation logic is part of your roadmap, it's worth asking whether they've shipped anything comparable - an AI recommendation engine case study from a past project, for instance, tells you far more about their real technical range than a slide claiming "AI/ML expertise" ever will. Anyone can put that phrase on a deck. Far fewer teams can show you the architecture behind a working one.

And when I'm doing formal due diligence on a specialized mobile app development company, I treat automated test coverage and infrastructure-as-code as the two highest-signal indicators in the entire process. Almost everything else in the pitch tends to fall into place - or fall apart - depending on whether those two things are genuinely there.

A Short, Honest Checklist Before You Sign

  • Request a real, unedited coverage report broken down by module
  • Ask to see actual Terraform, CloudFormation, or equivalent IaC sitting in their repo
  • Watch a live CI/CD pipeline run, including a failure case if you can get one
  • Get specifics on dependency scanning, secrets management, and recent pen-test findings
  • Pay attention to how fast - and how honestly - they answer, not just what the answer is

Thirty years into this, that last point is the one that hasn't changed. Trust what the artifacts show you over what the deck promises you. The vendors worth signing with tend to welcome this level of scrutiny, sometimes even seem relieved by it. The ones who deflect are telling you something too. Just make sure you're actually listening when they do.


Have you run technical due diligence on an outsourced dev team before? I'd genuinely like to hear what red flags you've caught in the process - drop them in the comments.

Top comments (1)

Collapse
 
melvinsteppe profile image
Melvin Steppe

Really useful points here. I especially liked the part about checking the actual development process instead of just looking at a company's portfolio. That's something businesses often overlook.