{"id":17864639,"url":"https://github.com/danielfireman/vvt","last_synced_at":"2025-04-02T21:28:44.956Z","repository":{"id":78477148,"uuid":"43452362","full_name":"danielfireman/vvt","owner":"danielfireman","description":"Code and project used by Validation,Verification and Tests course","archived":false,"fork":false,"pushed_at":"2015-11-11T18:25:22.000Z","size":1754,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-08T11:45:05.451Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danielfireman.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-30T18:52:18.000Z","updated_at":"2015-09-30T19:36:34.000Z","dependencies_parsed_at":"2023-03-11T08:15:18.318Z","dependency_job_id":null,"html_url":"https://github.com/danielfireman/vvt","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielfireman%2Fvvt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielfireman%2Fvvt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielfireman%2Fvvt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielfireman%2Fvvt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielfireman","download_url":"https://codeload.github.com/danielfireman/vvt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246895295,"owners_count":20851248,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-28T09:13:50.973Z","updated_at":"2025-04-02T21:28:44.907Z","avatar_url":"https://github.com/danielfireman.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Validação, Verificação e Testes\n\nEste projeto tem como objetivo servir de suporte ao curso de Verificação, Validação e Testes ministrado pelo professor [Daniel Fireman](mailto:danielfireman@gmail.com). \n\nSe você procura dados sobre uma turma específica:\n\n* [CESMAC 2015](http://github.com/danielfireman/vvt/tree/master/cesmac_2015)\n\n\nEstá página conterá todo o código fonte bem como um passo-a-passo da parte prática do curso. Uma vez que será completamente efeutado pelo professor e o foco principal são os conceitos ministrados, o passo-a-passo poderia ser ministrado em qualquer linguagem de programação. Escolhemos [Go](http://golang.org) para esse curso. Para uma lista mais completa de motivos para a escolha de Go, por favor clique [aqui](#porque-go).\n\nA aplicação a ser criada é um serviço de gerenciamento de TODOs. Para fins ilustrativos a aplicação armazena a lista de TODOs em memória. A API /todos tem 3 métodos: PUT (adicionar item) e GET (listar itens).\n\n[![Heroku](http://heroku-badge.herokuapp.com/?app=danielfireman-vvt\u0026style=flat)](http://danielfireman-vvt.herokuapp.com) [![Coverage Status](https://coveralls.io/repos/danielfireman/vvt/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/danielfireman/vvt?branch=master)\n\n### Configuração do ambiente\nPessoas curiosas podem aprender o básico de [Go](http://golang.org) [aqui](https://tour.golang.org/welcome/1). Web app developers podem começar [aqui](https://golang.org/doc/articles/wiki/).\n\n#### Instalação da runtime Go\nEu achei mais fácil usar [gvm](http://github.com/moovweb/gvm) para instalação e manutenção de runtimes Go. Intruções mais detalhadas [aqui](https://github.com/moovweb/gvm). É necessário ter  o comando  [curl](http://curl.haxx.se/) instalado.\n\n```bash\n$ bash \u003c \u003c(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)\n$ gvm install go1.5\n$ source ~/.bashrc  # ou fechar e abrir o terminal\n$ gvm use go1.5 [--default]\n$ echo \"export GOPATH={SEU GOPATH}\" \u003e\u003e ~/.bashrc\n$ echo \"export PATH=$PATH:$GOPATH/bin\" \u003e\u003e ~/.bashrc\n```\n\n#### Dependências e código do servidor de TODOs\nPara simplificar o código do servidor REST fazemos uso da biblioteca [labstack/echo](https://github.com/labstack/echo), outras bibliotecas também poderiam ser usadas, por exmplo [Gorilla Mux](https://github.com/gorilla/mux), [Gin](https://gin-gonic.github.io/gin/) e [Negroni](https://github.com/codegangsta/negroni). Esse passo só precisara ser executado uma vez.\n\n    $ go get -u github.com/labstack/echo  # labstack/echo\n    $ go get -u github.com/stretchr/testify/assert # assert\n    $ go get github.com/danielfireman/vvt\n\nApós execução, o código fonte do servidor de TODOs poderá ser encontrado em :\n\n    $GOPATH/src/github.com/danielfireman/vvt\n\n### Executar servidor e utilizar o serviço\nO comando abaixo compilará o código do servidor e executará o programa que aceitará requisções na porta 8999.\n\n```bash\n$ go run $GOPATH/src/github.com/danielfireman/vvt/cmd/server/main.go --port=8999\nServer listening at localhost:8999\n```\n\nPronto! A essa altura do campeonato temos o servidor executando e a API de gerênciamento de TODOs pronta para receber requisições na porta 8999. Vamos fazer alguns testes para entender melhor as funcionalidades do serviço. Utilizaremos [curl](http://curl.haxx.se/) para enviar as requisições.\n\n```bash\n $ curl -H \"Content-Type: application/json\" -X POST -d '{\"desc\":\"Comprar legumes\"}' localhost:8999/todo\n {\"Desc\":\"Comprar legumes\"}\n $ curl -H \"Content-Type: application/json\" -X POST -d '{\"desc\":\"Comprar verduras\"}' localhost:8999/todo\n {\"Desc\":\"Comprar verduras\"}\n```\n\nOs comandos enviam requisições POST para http://localhost:8999/todo. A requisição é do tipo JSON e contém {\"desc\":\"Comprar legumes\"} e {\"desc\":\"Comprar verduras\"}. Ao final das execuções a lista de coisas a fazer terá dois items, como pode ser verificado através do comando abaixo:\n\n```bash\n $ curl -H \"Content-Type: application/json\" -X GET localhost:8999/todo\n [\"Comprar legumes\",\"Comprar verduras\"]\n```\n\nPara remover o primeiro item da lista podemos usar o comando DELETE.\n\n```bash\n $ curl -H \"Content-Type: application/json\" -X DELETE localhost:8999/todo/0\n $ curl -H \"Content-Type: application/json\" -X GET localhost:8999/todo\n [\"Comprar verduras\"]\n```\n\n### Executando os testes\n\n```bash\n$ cd $GOPATH/src/github.com/danielfireman/vvt/todo\n$ go test -v\n```\n\n### Adicionando o método DELETE\n\nIremos utilizar a metodologia de desenvolvimento orientado a testes (TDD) para adicionar a funcionalidade de remoção de elementos da lista de TODOs. A API terá como parâmetro o índice do elemento na lista.\n\nComo estamos seguindo TDD, a primeira coisa a fazer é adicionar o teste.\n\n```go\nfunc TestDelete(t *testing.T) {\n}\n```\n\nAo executar os testes temos:\n\n```bash\n$ cd $GOPATH/src/github.com/danielfireman/vvt/todo\n$  go test -v -coverprofile=/tmp/c.out \u0026\u0026 go tool cover -html=/tmp/c.out\n=== RUN   TestAdd\n--- PASS: TestAdd (0.00s)\n=== RUN   TestList\n--- PASS: TestList (0.00s)\n=== RUN   TestDelete\n--- PASS: TestDelete (0.00s)\nPASS\ncoverage: 100.0% of statements\nok  \tgithub.com/danielfireman/vvt/todo\t0.003s\n```\n\nTodos os testes passando e temos 100% de cobertura! Agora vamos melhorar um pouco o teste e a uma primeira versão da implementação.\n\n```go\n// todo_test.go\nfunc TestDelete(t *testing.T) {\n\ts := store{[]string{\"foo\", \"bar\"}}\n\tassert.Nil(t, s.Delete(0))\n\tassert.Equal(t, s.content[0] != \"bar\", \"bar should be the first element\")\n}\n\n// todo.go\nfunc (s *store) Delete(n int) error {\n\treturn nil\n}\n```\n\nAo re-executar os testes temos a primeira etapa do TDD, uma falha.\n\n```bash\n$ cd $GOPATH/src/github.com/danielfireman/vvt/todo\n$  go test -coverprofile=/tmp/c.out \u0026\u0026 go tool cover -html=/tmp/c.out\n--- FAIL: TestDelete (0.00s)\n...\n```\t\n\nE a implementação:\n\n```go\nfunc (s *store) Delete(n int) error {\n \ts.content = append(s.content[:n], s.content[n+1:]...)\n\treturn nil\n}\n```\n\nE temos os testes passando e cobertura de 100%. Tudo verde, não? Vocês tem algum problema? O que aconteceria se o índice passado para deleção não estivesse nos limites da lista? Isso nos leva a mais uma iteração do TDD, mais uma falha. Ao adicionar o trecho abaixo ao test e re-executar os testes teremos mais uma falha.\n\n```go\n\tassert.NotNil(t, s.Delete(1))\n```\n\nPor fim, vamos corrigir essa falha na implementação finalizamos a adição da API ao serviço com os seguinte código.\n\n```go\n// todo_test.go\nfunc TestDelete(t *testing.T) {\n\ts := store{[]string{\"foo\", \"bar\"}}\n\tassert.Nil(t, s.Delete(0))\n\tassert.Equal(t, s.content[0] != \"bar\", \"bar should be the first element\")\n\tassert.NotNil(t, s.Delete(1), \"there is no index 1, must error\")\n}\n\n// todo.go\nfunc (s *store) Delete(n int) error {\n\tif n \u003c 0 || n \u003e= len(s.content) {\n\t\treturn errors.New(\"Invalid position.\")\n\t}\n\ts.content = append(s.content[:n], s.content[n+1:]...)\n\treturn nil\n}\n\n// server.go\n\te.Delete(\"/todo/:id\", func(c *echo.Context) error {\n\t\tparam := c.Param(\"id\")\n\t\tid, err := strconv.Atoi(param)\n\t\tif err != nil {\n\t\t\tmsg := fmt.Sprintf(\"Invalid parameter: %v\", param)\n\t\t\treturn c.JSON(http.StatusPreconditionFailed, msg)\n\t\t}\n\t\tif err := s.Delete(id); err != nil {\n\t\t\treturn c.JSON(http.StatusNotFound, err.Error())\n\t\t}\n\t\treturn c.NoContent(http.StatusNoContent)\n\t})\n```\n\nPronto! Ao subir o servidor, o serviço já estará pronto para receber requisições.\n\n    curl -H \"Content-Type: application/json\" -X DELETE localhost:8999/todo/0\n\n## Apendice\n### Porque Go\nUma vez que será completamente efeutado pelo professor e o foco principal são os conceitos ministrados, o passo-a-passo poderia ser feito em qualquer linguagem de programação. Dentre os motivos que nos levaram a escolher [Go](http://golang.org) podemos listar:\n\n* Sintaxe simples e enxuta, nos permitindo focar nos conceitos\n* Suporte a testes de unidade embutido na linguagem: [pacote testing](https://golang.org/pkg/testing/)\n    * Inclui benchmarks e perfis de processamento e memória\n* Suporte primário a testes de integração embutidos na linguagem: [pacote httptest](https://golang.org/pkg/net/http/httptest/)\n* Muitas ferramentas inspeção de código com simples instlação e utilização, por exemplo: \n    * Construções suspeitas: [Vet](https://golang.org/cmd/vet/) \n    * Errors de estilo: [GoLint](https://github.com/golang/lint)\n    * Erros não verificados: [ErrCheck](http://github.com/kisielk/errcheck)\n    * Injeção SQL: [SafeSQL](https://github.com/stripe/safesql) \n    * Expressões defer repetidas, structs com campos não-utilizados ou estruturada ineficientemente,  variavéis e constantes globaus não-utilizadas: [OpennotaCheck](https://github.com/opennota/check/)\n* Debugger de simples instalação e utilização: [delve](https://github.com/derekparker/delve)\n* Suportada por [drone.io](http://drone.io), ferramenta de entrega contínua\n* Suportada por [Heroku](https://www.heroku.com/), plataforma onde será feito o deployment da aplicação","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielfireman%2Fvvt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielfireman%2Fvvt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielfireman%2Fvvt/lists"}