Raible's Wiki

Raible Designs
Wiki Home
News
Recent Changes

AppFuse

Homepage
  - Korean
  - Chinese
  - Italian
  - Japanese

QuickStart Guide
  - Chinese
  - French
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish
  - Japanese

User Guide
  - Korean
  - Chinese

Tutorials
  - Chinese
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish

FAQ
  - Korean

Latest Downloads

Other Applications

Struts Resume
Security Example
Struts Menu

Set your name in
UserPreferences


Referenced by
Articles
Articles_pt
CreateManager_pt
ValidationAndList_pt




JSPWiki v2.2.33

[RSS]


Hide Menu

CreateActions_pt


Difference between version 9 and version 1:

At line 6 changed 1 line.
Este tutorial vai lhe mostrar como criar Actions Struts, um teste JUnit (utilizando [StrutsTestCase|http://strutstestcase.sourceforge.net/]), e um JSP para o formulário. A Action que criaremos se comunicará com o PersonManager criado no tutorial [Criando Managers|CreateManager_pt].
Este tutorial vai lhe mostrar como criar Actions Struts, um teste JUnit (utilizando [StrutsTestCase|http://strutstestcase.sourceforge.net/]), e um JSP para o formulário.
A Action que criaremos se comunicará com o PersonManager criado no tutorial [Criando Managers|CreateManager_pt].
At line 8 changed 1 line.
Por default, o AppFuse disponibiliza o [Struts|http://struts.apache.org] como seu framework web. Desde a versão 1.6+, podemos utilizar [Spring|http://www.springframework.org] ou [WebWork|http://opensymphony.org/webwork] como framework web. Na versão 1.7, foi adicionado suporte à utilização do [JSF|http://myfaces.apache.org] ou [Tapestry|http://jakarta.apache.org/tapestry].
Por default, o AppFuse disponibiliza o [Struts|http://struts.apache.org] como seu framework web.
Desde a versão 1.6+, podemos utilizar [Spring|http://www.springframework.org] ou [WebWork|http://opensymphony.org/webwork] como framework web.
Na versão 1.7, foi adicionado suporte à utilização do [JSF|http://myfaces.apache.org] ou [Tapestry|http://jakarta.apache.org/tapestry].
At line 10 changed 1 line.
Para instalar qualquer destes frameworks web ao invés de Struts, simplesmente devemos navegar para o diretório ''extras'' e entrar no diretório do framework que desejamos instalar. O arquivo README.txt deste diretório possui instruções mais detalhadas. Os tutoriais para estes frameworks estão listados abaixo.
Para instalar qualquer destes frameworks web ao invés de Struts, simplesmente devemos navegar para o diretório ''extras'' e entrar no diretório do framework que desejamos instalar.
O arquivo README.txt deste diretório possui instruções mais detalhadas.
Os tutoriais para estes frameworks estão listados abaixo.
At line 31 changed 1 line.
Agora vamos gerar nosso objeto PersonForm para Struts e nossa camada web. Para fazê-lo, é necessário adicionar tags XDoclet à classe Person.java para criar nosso ActionForm Struts. No JavaDoc para o arquivo Person.java, adicione as seguintes tags @struts.form (verifique o arquivo User.java se necessita de exemplos):
Agora vamos gerar nosso objeto PersonForm para Struts e nossa camada web.
Para fazê-lo, é necessário adicionar tags XDoclet à classe Person.java para criar nosso ActionForm Struts. No JavaDoc para o arquivo Person.java, adicione as seguintes tags @struts.form (verifique o arquivo User.java se necessita de exemplos):
At line 38 changed 1 line.
;:''We extend org.appfuse.webapp.form.BaseForm because it has a toString() method that allows us to call log.debug(formName) to print out a reader-friendly view of the Form object.''
;:''Estendemos org.appfuse.webapp.form.BaseForm porque ele possui um método toString() que nos permite chamar log.debug(formName) para nos mostrar um formato amigável do objeto Form em console.''
At line 40 changed 1 line.
;:''If you haven't renamed the "org.appfuse" packages to "com.company" or otherwise don't have your model class in the default package, you may need to fully-qualify the reference to org.appfuse.webapp.form.BaseForm in the @struts.form tag.''
;:''Se você ainda não renomeou os seus pacotes "org.appfuse" para "com.company" ou se você não possui sua classe de modelo no pacote default, você precisará de uma referência completa para org.appfuse.webapp.form.BaseForm na tag @struts.form.''
At line 42 changed 2 lines.
!!Create skeleton JSPs using XDoclet [#2]
In this step, you'll generate a JSP page to display information from the Person object. It will contain Struts' JSP tags that render table rows for each property in Person.java. The [AppGen] tool that's used to do this is based off a StrutsGen tool - which was originally written by [Erik Hatcher|http://www.blogscene.org/erik/]. It's basically just a couple of classes and a bunch of XDoclet templates. All these files are located in extras/appgen.
!!Criar esqueletos JSPs usando XDoclet [#2]
Nesta parte, geraremos uma página JSP para mostrar informações de um objeto Person. Esta página deve conter tags JSP Struts para renderizar linhas de tabela para cada propriedade do arquivo Person.java. A ferramenta [AppGen] que é utilizada para isto, baseada na ferramenta StrutsGen - que foi originalmente escrita por [Erik Hatcher|http://www.blogscene.org/erik/]. São basicamente algumas classes e alguns templates XDoclet. Todos estes arquivos estão localizados no diretório extras/appgen.
At line 45 changed 1 line.
Here are the simple steps to generating the JSP and a properties file containing the labels for the form elements:
Aqui estão passos simples para gerar os JSPs e arquivos de propriedades que contém os rótulos para os elementos do Formulário:
At line 47 changed 6 lines.
* From the command-line, navigate to "extras/appgen"
* Execute __ant -Dobject.name=Person -Dappgen.type=pojo__ to generate a bunch of files in extras/appgen/build/gen. In fact, it'll generate all the files you need to complete this tutorial. However, let's just grab the ones you need.
** web/WEB-INF/classes/Person.properties (labels for your form elements)
** web/pages/personForm.jsp (JSP file for viewing a single Person)
** web/pages/personList.jsp (JSP file for viewing a list of People)
* Copy the contents of Person.properties into web/WEB-INF/classes/ApplicationResources.properties. These are all the keys you will need for titles/headings and form properties. Here is an example of what you should add to ApplicationResources.properties:
* Da linha de comando, navegue para "extras/appgen"
* Execute __ant -Dobject.name=Person -Dappgen.type=pojo__ para gerar os arquivos em extras/appgen/build/gen. Na verdade, serão gerados todos os arquivos que você precisa para completar o tutorial. Mas por enquanto, vamos pegar apenas os arquivos necessários.
** web/WEB-INF/classes/Person.properties (Rótulos para nossos elementos de formulário)
** web/pages/personForm.jsp (arquivo JSP de detalhamento de um único objeto Person)
** web/pages/personList.jsp (arquivo JSP para mostrar uma lista de objetos Person)
* Copie o conteúdo do arquivo Person.properties no arquivo web/WEB-INF/classes/ApplicationResources.properties. Estas são todas as chaves que precisaremos para títulos/cabeçalhos e propriedades de formulário. Aqui está um exemplo do que deve ser adicionado ao arquivo ApplicationResources.properties (no nosso caso, ApplicationResources_pt.properties):
At line 55 changed 1 line.
# -- person form --
# -- formulário person --
At line 57 changed 2 lines.
personForm.firstName=First Name
personForm.lastName=Last Name
personForm.firstName=Primeiro Nome
personForm.lastName=Sobrenome
At line 60 changed 3 lines.
person.added=Person has been added successfully.
person.updated=Person has been updated successfully.
person.deleted=Person has been deleted successfully.
person.added=Person foi adicionado com sucesso.
person.updated=Person foi alterado com sucesso.
person.deleted=Person foi removido com sucesso.
At line 64 changed 3 lines.
# -- person list page --
personList.title=Person List
personList.heading=Persons
# -- página da lista de Person --
personList.title=Lista de Pessoas
personList.heading=Pessoas
At line 68 changed 3 lines.
# -- person detail page --
personDetail.title=Person Detail
personDetail.heading=Person Information
# -- página de detalhamento de Person --
personDetail.title=Detalhamento da Pessoa
personDetail.heading=Informações da Pessoa
At line 73 changed 1 line.
* Copy personForm.jsp to web/pages/personForm.jsp. Copy personList.jsp to web/pages/personList.jsp.
* Copie o arquivo personForm.jsp para web/pages/personForm.jsp. Copie o arquivo personList.jsp para web/pages/personList.jsp. __Perceba que cada um dos novos nomes de arquivo são iniciados com caracteres minúsculos.__
At line 75 changed 1 line.
;: ''The files in the "pages" directory will end up in "WEB-INF/pages" at deployment time. The container provides security for all files below WEB-INF. This applies to client requests, but not to forwards from Struts' ActionServlet. Placing all JSPs below WEB-INF ensures they are only accessed through Actions, and not directly by the client or each other. This allows security to be moved up into the Action, where it can be handled more efficiently, and out of the base presentation layer.''
;: ''Os arquivos no diretório "pages" terminarão em "WEB-INF/pages" em tempo de publicação. O container fornece segurança para todos os arquivos dentro de WEB-INF. Isto se aplica a requisições de cliente, mas não a envios para o ActionServlet do Struts. Deixando todos os JSPs dentro de WEB-INF assegura-se que eles serão acessados apenas por Actions, e não diretamente pelo cliente ou por outrém. Isto permite que a segurança seja movida para a Action, onde pode ser tratada com mais eficiência, e fora da base da camada de apresentação.''
At line 77 changed 1 line.
The web application security for AppFuse specifies that all *.html url-patterns should be protected (except for /signup.html and /passwordHint.html). This guarantees that clients must go through an Action to get to a JSP (or at least the ones in ''pages'').
A segurança da aplicação web para o AppFuse especifica que todos os padrões *.html devem ser protegidos (exceto /signup.html e /passwordHint.html). Isto garante que o cliente deve acessar uma Action para receber um JSP (ou ao menos os JSPs em ''pages'').
At line 79 changed 2 lines.
%%note __NOTE:__ If you want to customize the CSS for a particular page, you can add <body id="pageName"/> to the top of the file. This will be slurped up by SiteMesh and put into the final page. You can then customize your CSS on a page-by-page basis using something like the following:
{{{body#pageName element.class { background-color: blue } }}}%%
%%note __NOTA:__ Se você deseja customizar o CSS para uma página em particular, você pode adicionar <body id="nomeDaPagina"/> no início do arquivo. Isto será pego pelo SiteMesh e colocado ao final da página. Você pode então customizar seu CSS em uma base página-por-página utilizando algo assim:
{{{body#nomeDaPagina element.class { background-color: blue } }}}%%
At line 82 changed 2 lines.
* Add keys in ApplicationResources.properties the titles and headings in the JSPs
In the generated JSPs, there are two keys for the title (top of the browser window) and the header (heading in the page). These fields are provided above with key names of personDetail.title and personDetail.heading.
* Adicione chaves no arquivo ApplicationResources.properties (no nosso caso, ApplicationResources_pt.properties) para os títulos e cabeçalhos nos JSPs
Nos JSPs gerados, existem duas chaves: uma para o título (parte superior da janela do browser) e outra para o cabeçalho (cabeçalho na página). Estes campos são preenchidos acima com os nomes de chave de personDetail.title e personDetail.heading.
At line 85 changed 1 line.
''Just above, we added "personForm.*" keys to this file, so why do I use personDetail instead of personForm for the titles and headings? The best reason is because it gives a nice separation between form labels and text on the page. Another reason is because all the *Form.* give you a nice representation of all the fields in your database.
''Acima, nós adicionamos chaves "personForm.*" para este arquivo, então porque utilizar personDetail ao invés de personForm para os títulos e cabeçalhos? A melhor razão é porque isto nos dá uma boa separação entre rótulos de formulários e textos na página. Uma outra razão é que todos os *Form.* nos dão uma boa representação de todos os campos em nossa base de dados.
At line 87 changed 1 line.
I recently had a client who wanted all fields in the database searchable. This was fairly easy to do. I just looked up all the keys in ApplicationResources.properties which contained "Form." and then put them into a drop-down. On the UI, the user was able to enter a search term and select the column they wanted to search. I was glad I followed this Form vs. Detail distinction on that project!''
Eu recentemente tive um cliente que queria que todos os campos da base de dados fossem consultáveis. Isto foi razoavelmente fácil de fazer. Eu apenas procurei todas as chaves no arquivo ApplicationResources.properties que contém "Form." e então os coloquei em um drop-down(os selects html). Na UI(''User Interface'', ou interface para o usuário), o usuário era capaz de entrar um termo de busca e selecionar a coluna que ele queria consultar. Fiquei feliz de ter seguido esta distinção Form vs. Detail naquele projeto!''
At line 90 changed 2 lines.
!!Create PersonActionTest to test PersonAction [#3]
To create a StrutsTestCase Test for PersonAction, start by creating a PersonActionTest.java file in the test/web/**/action directory:
!!Criar a classe PersonActionTest para testar PersonAction [#3]
Para criar um teste StrutsTestCase para PersonAction, comece criando um arquivo PersonActionTest.java no diretório test/web/**/action:
At line 131 changed 1 line.
// update the form from the edit and add it back to the request
// altera o form da edição e o adiciona novamente à requisição
At line 153 changed 1 line.
You will need to add __PERSON_KEY__ as a variable to the src/dao/**/Constants.java class. The name, "personForm", matches the name given to the form in the struts-config.xml file.
Será necessário adicionar __PERSON_KEY__ como uma variável na classe src/dao/**/Constants.java . O nome, "personForm", combina com o nome dado ao form no arquivo struts-config.xml.
At line 158 changed 1 line.
* The request scope attribute that holds the person form.
* O atributo de escopo de requisição que mantém o formulário da pessoa.
At line 163 changed 1 line.
If you try to run this test, you will get a number of NoSuchMethodErrors - so let's define the edit, save, and delete methods in the PersonAction class.
Se tentarmos executar este teste, teremos muitos NoSuchMethodErrors - então vamos definir os métodos edit, save, e delete na classe PersonAction.
At line 165 changed 1 line.
!!Create PersonAction [#4]
!!Criar a classe PersonAction [#4]
At line 167 changed 1 line.
In src/web/**/action, create a PersonAction.java file with the following contents:
Em src/web/**/action, crie um arquivo PersonAction.java com o seguinte conteúdo:
At line 204 changed 1 line.
log.debug("Entering 'delete' method");
log.debug("Entrando no método 'delete'");
At line 210 changed 1 line.
// Exceptions are caught by ActionExceptionHandler
// Exceções são pegas pelo ActionExceptionHandler
At line 217 changed 1 line.
// save messages in session, so they'll survive the redirect
// salva a mensagem na sessão para ela sobreviver ao redirecionamento
At line 228 changed 1 line.
log.debug("Entering 'edit' method");
log.debug("Entrando no método 'edit'");
At line 233 changed 2 lines.
// if an id is passed in, look up the user - otherwise
// don't do anything - user is doing an add
// se um id é passado, procura o objeto Person - senão
// não faz nada - o usuário está fazendo uma adição
At line 250 changed 1 line.
log.debug("Entering 'save' method");
log.debug("Entrando no método 'save'");
At line 253 changed 1 line.
// Extract attributes and parameters we will need
// Extraindo atributos e parâmetros que iremos precisar
At line 259 changed 1 line.
log.debug("saving person: " + personForm);
log.debug("salvando person: " + personForm);
At line 266 changed 1 line.
// add success messages
// adiciona as mensagens de sucesso
At line 271 changed 1 line.
// save messages in session to survive a redirect
// salva a mensagem de sucesso na sessão, para sobreviver ao redirecionamento
At line 286 changed 2 lines.
You'll notice in the code above that there are many calls to to ''convert'' a PersonForm or a Person object. The ''convert'' method is in BaseAction.java (which calls ConvertUtil.convert()) and
uses
Perceba que o código acima possui várias chamadas a um método ''convert'' para um PersonForm ou para um objeto Person. O método ''convert'' está na classe BaseAction.java (que chama ConvertUtil.convert()) e
usa
At line 289 changed 1 line.
to convert POJOs → ActionForms and ActionForms → POJOs.
para a conversão POJOs → ActionForms e ActionForms → POJOs.
At line 291 changed 1 line.
;:''If you are running Eclipse, you might have to "refresh" the project in order to see PersonForm. It lives in build/web/gen, which should be one of your project's source folders. This is the only way for Eclipse to see and import PersonForm, since it is generated by XDoclet and does not live in your regular source tree. You can find it at build/web/gen/org/appfuse/webapp/form/PersonForm.java.''
;:''Se utilizarmos Eclipse, devemos atualizar ("refresh") o projeto para poder ver o PersonForm. Ele está em build/web/gen, que é uma das pastas de código do projeto. Esta é a única maneira do Eclipse ver e importar PersonForm, pela razão desta classe ser gerada pelo XDoclet e não pertencer à árvore normal de pastas de código do projeto. Podemos encontrar esta classe em build/web/gen/org/appfuse/webapp/form/PersonForm.java.''
At line 293 changed 1 line.
;:''In [BaseAction|http://raibledesigns.com/downloads/apptracker/api/org/appfuse/webapp/action/BaseAction.java.html] you can register additional Converters (i.e. [DateConverter|http://raibledesigns.com/downloads/apptracker/api/org/apptracker/util/DateConverter.java.html]) so that BeanUtils.copyProperties knows how to convert Strings → Objects. If you have Lists on your POJOs (i.e. for parent-child relationships), you will need to manually convert those using the {{convertLists(java.lang.Object)}} method.''
;:''Na classe [BaseAction|http://raibledesigns.com/downloads/apptracker/api/org/appfuse/webapp/action/BaseAction.java.html] podemos registrar conversores adicionais (i.e. [DateConverter|http://raibledesigns.com/downloads/apptracker/api/org/apptracker/util/DateConverter.java.html]) para que o BeanUtils.copyProperties saiba como fazer a conversão Strings → Objects. Se temos Lists em nossos POJOs (i.e. para relacionamentos pai-filho), teremos que converter manualmente estes utilizando o método {{convertLists(java.lang.Object)}}.''
At line 295 changed 1 line.
Now you need to add the ''edit'' forward and the ''savePerson'' action-mapping, both which are specified in in the PersonActionTest. To do this, add a couple more XDoclet tags to the top of the PersonAction.java file. Do this right above the class declaration. You should already have the XDoclet tag for the ''editPerson'' action-mapping, but I'm showing it here so you can see all the XDoclet tags at the top of this class.
Agora temos que adicionar os action-mapping de envio ''edit'' e ''savePerson'', ambos especificados em PersonActionTest. Para fazê-lo, adicionaremos algumas tags XDoclet na parte superior do arquivo PersonAction.java. Devemos fazer isto logo acima da declaração de classe. Já devemos ter a tag XDoclet para o action-mapping ''editPerson'', mas o mostrarei aqui para que todos possamos ver todas as tag XDoclet na parte superior da classe.
At line 311 changed 1 line.
The main difference between the ''editPerson'' and ''savePerson'' action-mappings is that ''savePerson'' has validation turned on (see validation="true") in the XDoclet tag above. Note that the "input" attribute must refer to a forward, and cannot be a path (i.e. /editPerson.html). If you'd prefer to use the save path for both edit and save, that's possible too. Just make sure validate="false", and then in your "save" method - you'll need to call form.validate() and handle errors appropriately.
A maior diferença entre os action-mappings ''editPerson'' e ''savePerson'' é que ''savePerson'' possui a validação ligada (veja validation="true") na tag XDoclet acima. Note que o atributo "input" deve se referir a um envio, não podendo ser um caminho(i.e. /editPerson.html). Se preferirmos utilizar o caminho para salvar tanto para edição quanto para persistência, isto é possível também. Apenas devemos nos certificar que o validate="false", e que no método "save" - devemos chamar form.validate() e tratar os erros adequadamente.
At line 313 changed 1 line.
You might notice that the code you're using to call the PersonManager is the same as the code used in the PersonManagerTest. Both PersonAction and PersonManagerTest are ''clients'' of PersonManagerImpl, so this makes perfect sense.
Você perceberá que o código que estamos utilizando para chamar o PersonManager é o mesmo código utilizado em PersonManagerTest. Tanto PersonAction quanto PersonManagerTest são ''clientes'' de PersonManagerImpl, então isto faz sentido perfeitamente.
At line 315 changed 1 line.
Everything is almost done for this tutorial, let's get to running the tests!
Tudo está quase pronto neste tutorial, vamos então rodar os testes!
At line 317 changed 1 line.
!!Run PersonActionTest [#5]
!!Rodar PersonActionTest [#5]
At line 319 changed 1 line.
If you look at our PersonActionTest, all the tests depend on having a record with id=1 in the database (and testRemove depends on id=2), so add that to our sample data file (metadata/sql/sample-data.xml). I'd add it at the bottom - order is not important since it (currently) does not relate to any other tables.
Se olharmos ao nosso PersonActionTest, todos os testes dependem da tupla com o id=1 no banco de dados (e o testRemove depende do id=2), então adicione ao nosso arquivo de amostra de dados (metadata/sql/sample-data.xml). Eu adicionaria ao final do arquivo - ordem não é importante porque (atualmente) não se relaciona com outras tabelas.
At line 339 changed 1 line.
DBUnit loads this file before we run any of our tests, so this record will be available to the PersonActionTest.
O DBUnit carrega este arquivo antes de rodar qualquer teste nosso, então estas tuplas serão disponíveis para o PersonActionTest.
At line 341 changed 1 line.
Now if you run __ant test-web -Dtestcase=PersonAction__ - everything should work as planned. Make sure Tomcat isn't running before you try this.
Agora se rodarmos __ant test-web -Dtestcase=PersonAction__ - tudo deve rodar como planejado. Certifique-se que o Tomcat não está rodando antes de tentar isto.
At line 349 added 1 line.
At line 346 changed 1 line.
!!Clean up the JSP to make it presentable [#6]
!!Formatar o JSP para deixá-lo apresentável [#6]
At line 348 changed 1 line.
Now let's clean up the generated personForm.jsp. Change the ''action'' of the <html:form> to be "savePerson" so validation will be turned on when saving. Also, change the ''focus'' attribute from focus="" to focus="firstName" so the cursor will be in the firstName field when the page loads (this is done with JavaScript).
Agora vamos "limpar" o personForm.jsp gerado. Mudaremos o atributo ''action'' do <html:form> para "savePerson" para ligar a validação quanto formos persistir. Mudaremos também o atributo ''focus'' de focus="" para focus="firstName" para o cursor estar no campo firstName quanto a página carregar (isto é feito via Javascript).
At line 350 changed 1 line.
Now if you execute __ant db-load deploy__, start Tomcat and point your browser to [http://localhost:8080/appfuse/editPerson.html?id=1], you should see something like this:
Outra coisa que devemos fazer é retirar os comentários das seguintes linhas no final do arquivo personForm.jsp. Isto é porque o Validator irá disparar uma exceção caso um nome de formulário for especificado no Validator e nenhuma regra de validação existir para ele.
At line 359 added 9 lines.
;:''Pessoalmente, eu acho isto um [bug|http://nagoya.apache.org/bugzilla/show_bug.cgi?id=27316], mas os commiters do Struts não concordam.''
{{{<html:javascript formName="personForm" cdata="false"
dynamicJavascript="true" staticJavascript="false"/>
<script type="text/javascript"
src="<html:rewrite page="/scripts/validator.jsp"/>"></script>}}}
Agora se executarmos __ant db-load deploy__, iniciarmos o Tomcat e apontarmos o browser para [http://localhost:8080/appfuse/editPerson.html?id=1], veremos algo como:
At line 356 removed 1 line.
%%note __NOTE:__ Use the __deploy-web__ target if you've changed any files under the ''web'' directory. Otherwise, use __deploy__ which compiles and deploys.%%
At line 358 changed 1 line.
Finally, to make this page more user friendly, you may want to add a message for your users at the top of the form, which can easily be done by adding text (using &lt;fmt:message&gt;) at the top of the personForm.jsp page.
%%note __NOTA:__ Utilize o alvo(target) __deploy-web__ se foram alterados apenas arquivos do diretórios ''web''. Senão, use __deploy__ que compila e publica.%%
At line 360 changed 2 lines.
!![[Optional] Create a Canoo WebTest to test browser-like actions [#7]
The final (optional) step in this tutorial is to create a [Canoo WebTest|http://webtest.canoo.com] to test the JSPs.
Finalmente, para tornarmos a página mais amigável, poderemos adicionar mensagens aos nossos usuários na parte superior do formulário, o que podemos fazer facilmente adicionando texto (utilizando &lt;fmt:message&gt;) na parte superior da página personForm.jsp.
At line 363 changed 1 line.
;:''I say this step is optional, because you can run the same tests through your browser.''
!![[Opcional] Criar WebTests Canoo para testar ações baseadas no browser [#7]
A parte final (opcional) para este tutorial é criar um [Canoo WebTest|http://webtest.canoo.com] para testar os JSPs.
At line 365 changed 1 line.
You can use the following URLs to test the different actions for adding, editing and saving a user.
;:''Digo que estes testes são opcionais, porque podemos rodar os mesmos testes no browser.''
At line 367 changed 4 lines.
* Add - [http://localhost:8080/appfuse/editPerson.html].
* Edit - [http://localhost:8080/appfuse/editPerson.html?id=1] (make sure and run __ant db-load__ first).
* Delete - [http://localhost:8080/appfuse/editPerson.html?method=Delete&amp;id=1] (or edit and click on the Delete button).
* Save - Click [edit|http://localhost:8080/appfuse/editPerson.html?id=1] and then click the Save button.
Podemos utilizar as seguintes URLs para testar as diferentes ações para adicionar, editar e persistir um Person.
At line 372 changed 1 line.
Canoo tests are pretty slick in that they're simply configured in an XML file. To add tests for add, edit, save and delete, open test/web/web-tests.xml and add the following XML. You'll notice that this fragment has a target named ''PersonTests'' that runs all the related tests.
* Adicionar - [http://localhost:8080/appfuse/editPerson.html].
* Editar - [http://localhost:8080/appfuse/editPerson.html?id=1] (make sure and run __ant db-load__ first).
* Remover - [http://localhost:8080/appfuse/editPerson.html?method=Delete&amp;id=1] (ou edite e clique no botão de remoção).
* Salvar - Acesse [edit|http://localhost:8080/appfuse/editPerson.html?id=1] e então clique o botão 'Salvar'.
At line 374 changed 1 line.
;:''I use CamelCase target names (vs. the traditional lowercase, dash-separated) because when you're typing ''-Dtestcase=Name'', I've found that I'm used to doing CamelCase for my JUnit Tests.''
Testes Canoo são simples, configurados apenas por um arquivo XML. Para adicionarmos testes para as operações CRUD(add, edit, save e delete), abriremos test/web/web-tests.xml e adicionaremos o seguinte XML. Note que este fragmento possui um alvo(target) nomeado ''PersonTests'' que executa todos os testes relacionados.
At line 391 added 2 lines.
;:''Utilizo notação composta(CamelCase) para os nomes de alvos (target)(vs. letras minúsculas tradicionais, separadas por hífen) por causa das execuções utilizando o JUnit, como por exemplo, ''-Dtestcase=Name'', Percebi que estou acostumado com a notação composta para meus testes JUnit.''
At line 378 changed 1 line.
<!-- runs person-related tests -->
<!-- roda os testes relacionados com Person -->
At line 381 changed 2 lines.
description="Call and executes all person test cases (targets)">
<echo>Successfully ran all Person JSP tests!</echo>
description="Chama e executa todos os casos de teste relacionados com Person (targets)">
<echo>Rodou todos os testes JSP de Person com sucesso!</echo>
At line 385 changed 1 line.
<!-- Verify the edit person screen displays without errors -->
<!-- Verifica se a tela de edição da pessoa mostra sem erros -->
At line 387 changed 1 line.
description="Tests editing an existing Person's information">
description="Testa a edição das informações de uma pessoa existente">
At line 392 changed 2 lines.
<invoke description="click Edit Person link" url="/editPerson.html?id=1"/>
<verifytitle description="we should see the personDetail title"
<invoke description="clica no link de edição de pessoa" url="/editPerson.html?id=1"/>
<verifytitle description="devemos ver o título do personDetail"
At line 399 changed 1 line.
<!-- Edit a person and then save -->
<!-- Edita a pessoa e então salva -->
At line 401 changed 1 line.
description="Tests editing and saving a user">
description="Testes editando e salvando a pessoa">
At line 406 changed 2 lines.
<invoke description="click Edit Person link" url="/editPerson.html?id=1"/>
<verifytitle description="we should see the personDetail title"
<invoke description="clica no link de edição de pessoas" url="/editPerson.html?id=1"/>
<verifytitle description="devemos ver o título da edição de pessoas"
At line 409 changed 3 lines.
<setinputfield description="set lastName" name="lastName" value="Canoo"/>
<clickbutton label="Save" description="Click Save"/>
<verifytitle description="Page re-appears if save successful"
<setinputfield description="seta o último nome" name="lastName" value="Canoo"/>
<clickbutton label="Save" description="Clica no botão Save"/>
<verifytitle description="A página reaparece se tudo ocorreu com sucesso"
At line 413 changed 1 line.
<verifytext description="verify success message" text="${person.updated}"/>
<verifytext description="verifica a mensagem de sucesso" text="${person.updated}"/>
At line 418 changed 1 line.
<!-- Add a new Person -->
<!-- Adiciona uma nova Pessoa -->
At line 420 changed 1 line.
description="Adds a new Person">
description="Adiciona uma nova Pessoa">
At line 425 changed 2 lines.
<invoke description="click Add Button" url="/editPerson.html"/>
<verifytitle description="we should see the personDetail title"
<invoke description="clica no botão de Adição" url="/editPerson.html"/>
<verifytitle description="deveremos ver o título do detalhamento da pessoa"
At line 428 changed 4 lines.
<setinputfield description="set firstName" name="firstName" value="Abbie"/>
<setinputfield description="set lastName" name="lastName" value="Raible"/>
<clickbutton label="${button.save}" description="Click button 'Save'"/>
<verifytitle description="Main Menu appears if save successful"
<setinputfield description="seta o firstName" name="firstName" value="Abbie"/>
<setinputfield description="seta o lastName" name="lastName" value="Raible"/>
<clickbutton label="${button.save}" description="Clica no botão 'Salvar'"/>
<verifytitle description="O menu principal reaparece se tudo ocorreu com sucesso"
At line 433 changed 1 line.
<verifytext description="verify success message" text="${person.added}"/>
<verifytext description="verifica a mensagem de sucesso" text="${person.added}"/>
At line 438 changed 1 line.
<!-- Delete existing person -->
<!-- Deleta uma pessoa existente -->
At line 440 changed 1 line.
description="Deletes existing Person">
description="Deleta uma pessoa existente">
At line 445 changed 4 lines.
<invoke description="click Edit Person link" url="/editPerson.html?id=1"/>
<clickbutton label="${button.delete}" description="Click button 'Delete'"/>
<verifytitle description="display Main Menu" text=".*${mainMenu.title}.*" regex="true"/>
<verifytext description="verify success message" text="${person.deleted}"/>
<invoke description="clica no link de edição da pessoa" url="/editPerson.html?id=1"/>
<clickbutton label="${button.delete}" description="Clica no botão 'Deletar'"/>
<verifytitle description="Mostra o menu principal se tudo ocorreu com sucesso" text=".*${mainMenu.title}.*" regex="true"/>
<verifytext description="verifica a mensagem de sucesso" text="${person.deleted}"/>
At line 454 changed 1 line.
After adding this, you should be able to run __ant test-canoo -Dtestcase=PersonTests__ with Tomcat running or __ant test-jsp -Dtestcase=PersonTests__ if you want Ant to start/stop Tomcat for you. To include the PersonTests when all Canoo tests are run, add it as a dependency to the "run-all-tests" target.
Após adicionar isto, seremos capazes de rodar __ant test-canoo -Dtestcase=PersonTests__ com o Tomcat rodando ou __ant test-jsp -Dtestcase=PersonTests__ se quisermos que o Ant inicialize e pare o Tomcat. Para incluir o PersonTests quando todos os testes canoo são executados, adicionaremos sua dependência ao alvo(target) "run-all-tests".
At line 456 changed 1 line.
You'll notice that there's no logging in the client-side window by Canoo. If you'd like to see what it's doing, you can add the following between &lt;/webtest&gt; and &lt;/target&gt; at the end of each target.
Você perceberá que não há registro(logging) na janela cliente do canoo. Se desejarmos ver o que o Canoo está fazendo, podemos adicionar o seguinte código entre &lt;/canoo&gt; e &lt;/target&gt; no final do alvo(target).
At line 468 changed 1 line.
''Next Up:'' __Part IV:__ [Adding Validation and List Screen|ValidationAndList] - Adding validation logic to the personForm so that firstName and lastName are required fields and adding a list screen to display all person records in the database.
''Próximo:'' __Parte IV:__ [Adicionando Validação e Tela de Listagem|ValidationAndList_pt] - Adicionando lógica de validação para o personForm para que o firstName e o lastName sejam campos obrigatórios, e adicionando uma tela de listagem para mostrar todas as tuplas de pessoas no banco de dados.

Back to CreateActions_pt, or to the Page History.