Prima di rispondere a una domanda del genere, devi decidere cosa vuoi raggiungere.
Scrivi il codice. Speri che rispetti il suo contratto (in altre parole, fa quello che dovrebbe fare. Annotare ciò che dovrebbe fare è un enorme passo avanti per alcune persone).
Per essere ragionevolmente convinto che il codice faccia ciò che deve fare, lo fissi abbastanza a lungo, o scrivi un codice di test che verifica un numero sufficiente di casi per convincerti "se il codice supera tutti questi test, allora è corretto ".
Spesso ti interessa solo l'interfaccia definita pubblicamente di alcuni codici. Se utilizzo la tua libreria, non mi interessa come hai fatto a farlo funzionare correttamente, solo che fa funziona correttamente. Verifico che la tua libreria sia corretta eseguendo i test unitari.
Ma stai creando la libreria. Farlo 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 test unitari per metodi privati" è abbastanza inutile. Tu vuoi test per questi metodi privati. Forse qualcuno ti dice che l'unità che testa i metodi privati è sbagliata. Ma questo significa solo che potresti non chiamarli "unit test" ma "test privati" o qualsiasi altra cosa ti piaccia chiamarli.
Il linguaggio Swift risolve il problema che non vuoi esporre A, B, C come metodi pubblici solo perché vuoi testarlo dando alle funzioni un attributo "testabile". Il compilatore consente di chiamare i metodi testabili privati dai test unitari, ma non dal codice non test.