Prima di rispondere a una domanda del genere, devi decidere cosa vuoi effettivamente ottenere.
Scrivi il codice. Speri che adempia al suo contratto (in altre parole, fa quello che dovrebbe fare. Annotare ciò che dovrebbe fare è un enorme passo in avanti per alcune persone).
Per essere ragionevolmente convinto che il codice faccia quello che dovrebbe fare, o lo fissi abbastanza a lungo, o scrivi un codice di prova che verifica abbastanza casi per convincerti "se il codice supera tutti questi test allora è corretto".
Spesso sei interessato solo all'interfaccia definita pubblicamente di alcuni codici. Se uso la libreria, non mi importa come hai fatto funziona correttamente, solo che fa il lavoro in modo corretto. Verifica che la tua biblioteca sia corretta eseguendo test unitari.
Ma stai creando la libreria. Far funzionare correttamente può essere difficile da raggiungere. Diciamo che mi interessa solo che la libreria esegua correttamente l'operazione X, quindi ho un test unitario per X. Tu, lo sviluppatore responsabile della creazione della libreria, implementa X combinando i passaggi A, B e C, che sono totalmente non banali. Per far funzionare la tua libreria, aggiungi dei test per verificare che A, B e C funzionino correttamente. Vuoi questi test. Dire "non dovresti avere unit test per metodi privati" non ha senso. Si desidera che i test per questi metodi privati. Forse qualcuno ti dice che l'unità che verifica i metodi privati è sbagliata. Questo significa solo che potresti non chiamarli "test unitari" ma "test privati" o come preferisci chiamarli.
Il linguaggio Swift risolve il problema che non si desidera esporre A, B, C come metodi pubblici solo perché si desidera testarlo assegnando alle funzioni un attributo "testabile". Il compilatore consente di chiamare metodi testabili privati dai test unitari, ma non dal codice non test.