Domanda

Vorrei poter inviare un modulo in un sorgente HTML (stringa) . In altre parole, ho bisogno almeno della capacità di generare i parametri POST da una stringa contenente l'origine HTML del modulo . Ciò è necessario nei test unitari per un progetto Django. Vorrei una soluzione che possibilmente;

  • Utilizza solo la libreria Python standard e Django.
  • Consente la generazione di parametri da un modulo specifico se è presente più di un modulo.
  • Mi consente di modificare i valori prima dell'invio.

Una soluzione che restituisce un'istanza di modulo (Django) da una data classe di form è la migliore. Perché mi permetterebbe di usare la validazione. Idealmente, consumerebbe l'origine (che è una stringa), una classe di modulo e facoltativamente un nome di modulo e restituire l'istanza com'era prima del rendering.

NOTA: sono consapevole che questo non è un compito facile e probabilmente i guadagni difficilmente giustificheranno lo sforzo necessario. Ma sono solo curioso di sapere come farlo, in modo pratico e affidabile. Se possibile.

È stato utile?

Soluzione

Dovresti rileggere la relativa al framework di test di Django , in particolare la parte relativa al test di viste (e moduli) con il client di test .

Il client di test funge da semplice browser Web e consente di inviare richieste GET e POST alle visualizzazioni Django. Puoi leggere l'HTML di risposta o ottenere lo stesso oggetto Context ricevuto dal modello. Il tuo oggetto Context dovrebbe contenere gli attuali form.Form che stai cercando.

Ad esempio, se la tua vista nell'URL / form / passa il contesto {'myform': forms.Form ()} al modello, potresti arrivare in questo modo:

from django.test.client import Client
c = Client()

# request the web page:
response = c.get('/form/')

# get the Form object:
form = response.context['myform']

form_data = form.cleaned_data
my_form_data = {} # put your filled-out data in here...
form_data.update(my_form_data)

# submit the form back to the web page:
new_form = forms.Form(form_data)
if new_form.is_valid():
    c.post('/form/', new_form.cleaned_data)

Speriamo che realizzi quello che vuoi, senza dover fare confusione con l'analisi dell'HTML.

Modifica : dopo aver riletto i documenti Django sui moduli, si scopre che i moduli sono immutabili. Va bene, però, basta creare una nuova istanza Form e inviarla; Ho modificato il mio esempio di codice in modo che corrisponda a questo.

Altri suggerimenti

Dato che il framework di test di Django fa questo, non sono sicuro di cosa tu stia chiedendo.

Vuoi testare un'app Django che ha un modulo?

  • In tal caso, devi fare un GET iniziale
  • seguito dal POST risultante

Vuoi scrivere (e testare) un'app Django che invia un modulo a un altro sito?

Ecco come testiamo le app di Django con i moduli.

class Test_HTML_Change_User( django.test.TestCase ):
    fixtures = [ 'auth.json', 'someApp.json' ]
    def test_chg_user_1( self ):
        self.client.login( username='this', password='this' )
        response= self.client.get( "/support/html/user/2/change/" )
        self.assertEquals( 200, response.status_code )
        self.assertTemplateUsed( response, "someApp/user.html")

def test_chg_user( self ):
    self.client.login( username='this', password='this' )
    # The truly fussy would redo the test_chg_user_1 test here
    response= self.client.post(
        "/support/html/user/2/change/",
        {'web_services': 'P',
         'username':'olduser',
         'first_name':'asdf',
         'last_name':'asdf',
         'email':'asdf@asdf.com',
         'password1':'passw0rd',
         'password2':'passw0rd',} )
    self.assertRedirects(response, "/support/html/user/2/" )
    response= self.client.get( "/support/html/user/2/" )
    self.assertContains( response, "<h2>Users: Details for", status_code=200 )
    self.assertContains( response, "olduser" )
    self.assertTemplateUsed( response, "someApp/user_detail.html")

Nota: non analizziamo l'HTML in dettaglio. Se ha il modello giusto e ha la stringa di risposta giusta, deve essere giusto.

È semplice ... e difficile allo stesso tempo.
Disclaimer: non so molto di Python e niente di Django ... Quindi do consigli generali, non linguistici ... Se uno dei suddetti consigli non funziona per te, ti consigliamo di farlo manualmente:

  • Carica la pagina con un parser HTML, elenca i moduli.
  • Se l'attributo method è POST (senza distinzione tra maiuscole e minuscole), ottenere l'attributo action per ottenere l'URL della richiesta (può essere relativo).
  • Nel modulo, ottieni tutti i tag input e select . Gli attributi name (o id se nessun nome) sono le chiavi dei parametri della richiesta. Gli attributi value (vuoto se assente) sono i valori corrispondenti.
  • Per seleziona , il valore è quello dell'opzione selezionata o il testo visualizzato non è un attributo value .

Questi nomi e valori devono essere codificati nell'URL nelle richieste GET, ma non in quelle POST.

HTH.

Scopri meccanizzare o è il wrapper twill . Penso che sia ClientForm funzionerà per te.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top