DEV Community

Cover image for A importancia de fazer testes
André Santos Meireles
André Santos Meireles

Posted on

A importancia de fazer testes

Em um sistema que estava desenvolvendo me deparei com a seguinte demanda, ler um arquivo csv e devolver seu primeiro resultado para analise, um arquivo csv podem vir com a primeira linha sendo um cabeçalho, logo essa linha deve ser ignorada e a segunda linha deve ser retornada ao invés da primeira.

O codigo para essa tarefa é simples.

public function getFirstContent(string $filename, UploadedFile $file, bool $hasHeader = false): array
    {
        $openFile = $file->openFile();
        $csv = [];
        while (($row = $openFile->fgets()) !== false) {
            if ($hasHeader) {
                continue;
            }
            $csv = str_getcsv($row);
            break;
        }
        $openFile = null;
        $file->storeAs(self::SAVE_DIR, $filename);

        return $csv;
    }
Enter fullscreen mode Exit fullscreen mode

Você pode ter notado o erro desta implementação, eu não. Após terminar de fazer esse código fui fazer os testes desta função. Escrevi testes com um caso onde o csv não teria um cabeçalho e o outro teria um cabeçalho, um teste deveria chamar a função fgets uma vez e outro duas, eis o codigo do teste

/**
     * @dataProvider cases
     */
    public function testGetFistContent(bool $hasHeader, array $fgets, string $expected): void
    {
        // arrange
        $splFileMock = $this->getMockBuilder(SplFileObject::class)
                            ->setConstructorArgs(['php://memory'])
                        ->getMock();
        $splFileMock->expects($this->exactly(count($fgets)))->method('fgets')->willReturnOnConsecutiveCalls(...$fgets);

        $file = $this->createMock(UploadedFile::class);
        $file->expects($this->once())->method('openFile')->willReturn($splFileMock);
        $file->expects($this->once())->method('storeAs')->with('/tmp', 'file.csv');

        // act
        $result = $this->service->getFirstContent('file.csv', $file, $hasHeader);

        // assert
        $this->assertIsArray($result);
        $this->assertSame($expected, $result[0]);
    }

public function cases(): array
    {
        return [
            [false, ['a,b,c'], 'a'],
            [true, ['a,b,c', 'c,b,a'], 'c']
        ];
    }
Enter fullscreen mode Exit fullscreen mode

O primeiro teste rodou de forma correta e passou, o segundo caso, onde o cabeçalho existe e deve ser pulada não estava passando, justamente porque $hasHeader nunca muda seu estado, logo quando for true, sempre irá pular a linha e nunca lerá o csv, um erro simples, fácil de ser corrigido, porém com um alto potencial de quebrar sistemas, imagine o quando de processamento desnecessário um loop infinito irá gerar?

Ao notar isso adicionei a uma linha de correção, um simples $hasHeader = false e pronto, o teste passou.

while (($row = $openFile->fgets()) !== false) {
            if ($hasHeader) {
                $hasHeader = false;
                continue;
            }
            $csv = str_getcsv($row);
            break;
}
Enter fullscreen mode Exit fullscreen mode

Testes são importantes para prevenir erros de falta de atenção, que podem ocorrer quando estamos com um prazo apertado ou no dia em que não estamos muito inspirados.

Sempre teste seu código, até mais!

Top comments (0)