O bug que eu registrei estava errado, e a fixture que consertou ele quebrou quatro outros testes
Eu mesmo registrei essa issue, a partir de um bug report: “não permitir álbuns duplicados na playlist.” Descrevi como um problema em tempo de escrita: adicionar uma verificação antes de inserir uma faixa para que um álbum duplicado não conseguisse entrar na playlist duas vezes. A deduplicação em nível de faixa já existia; achei que a lacuna estava no nível do álbum.
Antes de mexer no código, uma etapa de pesquisa que eu tinha disparado apontou um problema na minha própria issue: a proteção proposta era redundante em todos os lugares onde de fato dispararia (readições exatas já eram pegas pela verificação existente em nível de faixa), e inútil para o único caso que realmente poderia gerar um duplicado, uma edição deluxe ou remasterizada, cujos títulos de faixa diferem o suficiente para escapar de uma chave baseada em título. Eu estava prestes a construir uma correção para um bug que não podia acontecer, e ia deixar passar o que podia.
Então, em vez de corrigir a issue como registrada, voltei ao que eu realmente queria como pessoa que usa esse app, e isso reformulou tudo: se o álbum já está na playlist, ele não deveria aparecer na aba Discover de jeito nenhum, e a opção de adicioná-lo deveria ficar desabilitada em todo lugar, com uma mensagem dizendo que ele já está lá. Não é uma proteção em tempo de escrita, é uma exclusão em tempo de leitura. Se um álbum já está na sua playlist, nem mostre ele como algo para adicionar, de cara.
A implementação foi direta assim que o escopo ficou correto: calcular o conjunto de chaves de álbuns já presentes na playlist, filtrá-los do feed do Discover, e checar a associação antes de mostrar um botão “Add” em qualquer outro lugar. Adicionei uma fixture permanente de regressão aos dados mockados para isso, um álbum real do catálogo (“Fragments”, do Bonobo) também presente como item da playlist, para que a exclusão tivesse algo concreto para provar nos testes e no simulador.
Essa mesma fixture foi o que quebrou quatro testes sem relação nenhuma com a mudança. Adicionar um quinto grupo de playlist à fixture mockada compartilhada não mudou nada estruturalmente, mas quatro testes diferentes tinham suposições fixas embutidas, groups.count == 4, uma lista de sugestões que esperava incluir um álbum que agora, corretamente, estava excluído por já pertencer à playlist. Nenhum desses testes estava errado quando foi escrito; eles só tinham silenciosamente passado a depender de um número que nunca deveria ter sido determinante. Rodar a suíte inteira, em vez de só o teste novo, pegou os quatro antes que fossem para produção.
Verificar em um dispositivo real revelou mais duas coisas, nenhuma delas relacionada à funcionalidade que eu estava testando. A aba Playlist às vezes ficava travada para sempre em “Loading playlist…”, sem erro, sem nova tentativa, rastreada até uma busca concorrente recém-introduzida (o próprio prefetch em segundo plano do Discover agora também pede o conteúdo da playlist na inicialização) competindo com o carregamento da própria aba Playlist, caindo em um cancelamento silencioso e irrecuperável que já estava engolido no código. E um relato sobre configurações de filtro acabou não sendo um bug: um filtro de sugestões “More from artist” que uma sessão anterior tinha deliberadamente definido como independente do filtro principal da playlist, documentado como tal em um comentário que aparentemente eu mesmo tinha escrito e depois esquecido. As duas coisas ganharam suas próprias issues, em vez de serem silenciosamente incorporadas a essa aqui ou, pior, adivinhadas e “corrigidas” errado.
Leitura relacionada
Um segfault que não era um bug, e a API que eu finalmente apaguei
Uma limpeza da camada de serviço do MusicKit em que apagar métodos mortos travou todos os testes de uma vez, e a solução foi um build limpo, não um debugger.
Fechando as lacunas de teste: lógica pura, um branch de mock inalcançável, e uma virada para Swift 6
Extraindo algoritmos para fora do alcance do MusicKit, um parâmetro de mock que era silenciosamente ignorado, e dois testes que vinham passando pelo motivo errado o tempo todo.
Meus mocks não conseguiam falhar: injeção de erro e um crash de isolamento no Swift 6
Todo branch de catch era código morto nos testes. Uma costura de falha de 15 linhas resolveu isso, e depois uma suíte de testes sem anotação derrubou o runner inteiro.
Você também pode achar útil
Proton VPN
VPN comercial com filtragem NetShield e interruptor de desligamento automático.
Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).
Saiba maisAdGuard para iOS
Bloqueio de anúncios e rastreadores em todo o sistema no iOS, sem necessidade de um servidor DNS separado.
Como afiliado da AdGuard, ganho com compras qualificadas.
Saiba maisRackNerd VPS
Hospedagem VPS econômica para serviços leves que funcionam continuamente.
Como afiliado da RackNerd, ganho com compras qualificadas.
Saiba mais